src/jdk/nashorn/internal/objects/Global.java

Wed, 20 Aug 2014 18:59:11 +0530

author
sundar
date
Wed, 20 Aug 2014 18:59:11 +0530
changeset 964
8f2ed41abb26
parent 963
e2497b11a021
child 1006
e94bfa3c6c6c
permissions
-rw-r--r--

8050078: Nashorn ClassFilter Support
Reviewed-by: attila, hannesw, jlaskey, lagergren

jlaskey@3 1 /*
jlaskey@7 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
jlaskey@3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jlaskey@3 4 *
jlaskey@3 5 * This code is free software; you can redistribute it and/or modify it
jlaskey@3 6 * under the terms of the GNU General Public License version 2 only, as
jlaskey@3 7 * published by the Free Software Foundation. Oracle designates this
jlaskey@3 8 * particular file as subject to the "Classpath" exception as provided
jlaskey@3 9 * by Oracle in the LICENSE file that accompanied this code.
jlaskey@3 10 *
jlaskey@3 11 * This code is distributed in the hope that it will be useful, but WITHOUT
jlaskey@3 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jlaskey@3 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jlaskey@3 14 * version 2 for more details (a copy is included in the LICENSE file that
jlaskey@3 15 * accompanied this code).
jlaskey@3 16 *
jlaskey@3 17 * You should have received a copy of the GNU General Public License version
jlaskey@3 18 * 2 along with this work; if not, write to the Free Software Foundation,
jlaskey@3 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jlaskey@3 20 *
jlaskey@3 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jlaskey@3 22 * or visit www.oracle.com if you need additional information or have any
jlaskey@3 23 * questions.
jlaskey@3 24 */
jlaskey@3 25
jlaskey@3 26 package jdk.nashorn.internal.objects;
jlaskey@3 27
attila@963 28 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
sundar@372 29 import static jdk.nashorn.internal.lookup.Lookup.MH;
attila@963 30 import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
jlaskey@3 31 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
jlaskey@3 32 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
jlaskey@3 33
jlaskey@3 34 import java.io.IOException;
jlaskey@3 35 import java.io.PrintWriter;
attila@963 36 import java.lang.invoke.CallSite;
attila@963 37 import java.lang.invoke.ConstantCallSite;
jlaskey@3 38 import java.lang.invoke.MethodHandle;
jlaskey@3 39 import java.lang.invoke.MethodHandles;
attila@963 40 import java.lang.invoke.MethodType;
attila@963 41 import java.lang.invoke.SwitchPoint;
sundar@136 42 import java.lang.reflect.Field;
jlaskey@342 43 import java.util.Arrays;
attila@963 44 import java.util.HashMap;
jlaskey@3 45 import java.util.Map;
sundar@489 46 import java.util.concurrent.Callable;
sundar@489 47 import java.util.concurrent.ConcurrentHashMap;
attila@963 48 import java.util.concurrent.atomic.AtomicReference;
attila@963 49 import javax.script.ScriptContext;
attila@963 50 import javax.script.ScriptEngine;
attila@90 51 import jdk.internal.dynalink.linker.GuardedInvocation;
attila@90 52 import jdk.internal.dynalink.linker.LinkRequest;
sundar@964 53 import jdk.nashorn.api.scripting.ClassFilter;
attila@963 54 import jdk.nashorn.api.scripting.ScriptObjectMirror;
attila@963 55 import jdk.nashorn.internal.codegen.ApplySpecialization;
attila@963 56 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
sundar@690 57 import jdk.nashorn.internal.lookup.Lookup;
jlaskey@3 58 import jdk.nashorn.internal.objects.annotations.Attribute;
jlaskey@3 59 import jdk.nashorn.internal.objects.annotations.Property;
jlaskey@3 60 import jdk.nashorn.internal.objects.annotations.ScriptClass;
jlaskey@3 61 import jdk.nashorn.internal.runtime.ConsString;
jlaskey@3 62 import jdk.nashorn.internal.runtime.Context;
attila@963 63 import jdk.nashorn.internal.runtime.GlobalConstants;
jlaskey@3 64 import jdk.nashorn.internal.runtime.GlobalFunctions;
jlaskey@3 65 import jdk.nashorn.internal.runtime.JSType;
jlaskey@3 66 import jdk.nashorn.internal.runtime.NativeJavaPackage;
attila@663 67 import jdk.nashorn.internal.runtime.PropertyDescriptor;
hannesw@380 68 import jdk.nashorn.internal.runtime.PropertyMap;
attila@663 69 import jdk.nashorn.internal.runtime.Scope;
sundar@118 70 import jdk.nashorn.internal.runtime.ScriptEnvironment;
jlaskey@3 71 import jdk.nashorn.internal.runtime.ScriptFunction;
jlaskey@3 72 import jdk.nashorn.internal.runtime.ScriptObject;
jlaskey@3 73 import jdk.nashorn.internal.runtime.ScriptRuntime;
jlaskey@3 74 import jdk.nashorn.internal.runtime.ScriptingFunctions;
attila@663 75 import jdk.nashorn.internal.runtime.arrays.ArrayData;
sundar@459 76 import jdk.nashorn.internal.runtime.linker.Bootstrap;
jlaskey@3 77 import jdk.nashorn.internal.runtime.linker.InvokeByName;
attila@663 78 import jdk.nashorn.internal.runtime.regexp.RegExpResult;
jlaskey@131 79 import jdk.nashorn.internal.scripts.JO;
jlaskey@3 80
jlaskey@3 81 /**
jlaskey@3 82 * Representation of global scope.
jlaskey@3 83 */
jlaskey@3 84 @ScriptClass("Global")
sundar@771 85 public final class Global extends ScriptObject implements Scope {
attila@963 86 // Placeholder value used in place of a location property (__FILE__, __DIR__, __LINE__)
attila@963 87 private static final Object LOCATION_PROPERTY_PLACEHOLDER = new Object();
sundar@489 88 private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
sundar@489 89 private final InvokeByName VALUE_OF = new InvokeByName("valueOf", ScriptObject.class);
jlaskey@3 90
attila@963 91 /**
attila@963 92 * Optimistic builtin names that require switchpoint invalidation
attila@963 93 * upon assignment. Overly conservative, but works for now, to avoid
attila@963 94 * any complicated scope checks and especially heavy weight guards
attila@963 95 * like
attila@963 96 *
attila@963 97 * <pre>
attila@963 98 * public boolean setterGuard(final Object receiver) {
attila@963 99 * final Global global = Global.instance();
attila@963 100 * final ScriptObject sobj = global.getFunctionPrototype();
attila@963 101 * final Object apply = sobj.get("apply");
attila@963 102 * return apply == receiver;
attila@963 103 * }
attila@963 104 * </pre>
attila@963 105 *
attila@963 106 * Naturally, checking for builtin classes like NativeFunction is cheaper,
attila@963 107 * it's when you start adding property checks for said builtins you have
attila@963 108 * problems with guard speed.
attila@963 109 */
attila@963 110 public final Map<String, SwitchPoint> optimisticFunctionMap;
attila@963 111
attila@963 112 /** Name invalidator for things like call/apply */
attila@963 113 public static final Call BOOTSTRAP = staticCall(MethodHandles.lookup(), Global.class, "invalidateNameBootstrap", CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
attila@963 114
attila@963 115 /** Nashorn extension: arguments array */
attila@963 116 @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
attila@963 117 public Object arguments;
attila@963 118
jlaskey@3 119 /** ECMA 15.1.2.2 parseInt (string , radix) */
jlaskey@3 120 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 121 public Object parseInt;
jlaskey@3 122
jlaskey@3 123 /** ECMA 15.1.2.3 parseFloat (string) */
jlaskey@3 124 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 125 public Object parseFloat;
jlaskey@3 126
jlaskey@3 127 /** ECMA 15.1.2.4 isNaN (number) */
jlaskey@3 128 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 129 public Object isNaN;
jlaskey@3 130
jlaskey@3 131 /** ECMA 15.1.2.5 isFinite (number) */
jlaskey@3 132 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 133 public Object isFinite;
jlaskey@3 134
jlaskey@3 135 /** ECMA 15.1.3.3 encodeURI */
jlaskey@3 136 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 137 public Object encodeURI;
jlaskey@3 138
jlaskey@3 139 /** ECMA 15.1.3.4 encodeURIComponent */
jlaskey@3 140 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 141 public Object encodeURIComponent;
jlaskey@3 142
jlaskey@3 143 /** ECMA 15.1.3.1 decodeURI */
jlaskey@3 144 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 145 public Object decodeURI;
jlaskey@3 146
jlaskey@3 147 /** ECMA 15.1.3.2 decodeURIComponent */
jlaskey@3 148 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 149 public Object decodeURIComponent;
jlaskey@3 150
jlaskey@3 151 /** ECMA B.2.1 escape (string) */
jlaskey@3 152 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 153 public Object escape;
jlaskey@3 154
jlaskey@3 155 /** ECMA B.2.2 unescape (string) */
jlaskey@3 156 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 157 public Object unescape;
jlaskey@3 158
jlaskey@3 159 /** Nashorn extension: global.print */
jlaskey@3 160 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 161 public Object print;
jlaskey@3 162
jlaskey@3 163 /** Nashorn extension: global.load */
jlaskey@3 164 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 165 public Object load;
jlaskey@3 166
jlaskey@317 167 /** Nashorn extension: global.loadWithNewGlobal */
jlaskey@317 168 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@317 169 public Object loadWithNewGlobal;
jlaskey@317 170
jlaskey@75 171 /** Nashorn extension: global.exit */
jlaskey@75 172 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@75 173 public Object exit;
jlaskey@75 174
jlaskey@75 175 /** Nashorn extension: global.quit */
jlaskey@75 176 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@75 177 public Object quit;
jlaskey@75 178
jlaskey@3 179 /** Value property NaN of the Global Object - ECMA 15.1.1.1 NaN */
jlaskey@3 180 @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
attila@963 181 public final double NaN = Double.NaN;
jlaskey@3 182
jlaskey@3 183 /** Value property Infinity of the Global Object - ECMA 15.1.1.2 Infinity */
jlaskey@3 184 @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
attila@963 185 public final double Infinity = Double.POSITIVE_INFINITY;
jlaskey@3 186
jlaskey@3 187 /** Value property Undefined of the Global Object - ECMA 15.1.1.3 Undefined */
jlaskey@3 188 @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
jlaskey@3 189 public final Object undefined = UNDEFINED;
jlaskey@3 190
jlaskey@3 191 /** ECMA 15.1.2.1 eval(x) */
jlaskey@3 192 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 193 public Object eval;
jlaskey@3 194
jlaskey@3 195 /** ECMA 15.1.4.1 Object constructor. */
jlaskey@3 196 @Property(name = "Object", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 197 public volatile Object object;
jlaskey@3 198
jlaskey@3 199 /** ECMA 15.1.4.2 Function constructor. */
jlaskey@3 200 @Property(name = "Function", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 201 public volatile Object function;
jlaskey@3 202
jlaskey@3 203 /** ECMA 15.1.4.3 Array constructor. */
jlaskey@3 204 @Property(name = "Array", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 205 public volatile Object array;
jlaskey@3 206
jlaskey@3 207 /** ECMA 15.1.4.4 String constructor */
jlaskey@3 208 @Property(name = "String", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 209 public volatile Object string;
jlaskey@3 210
jlaskey@3 211 /** ECMA 15.1.4.5 Boolean constructor */
jlaskey@3 212 @Property(name = "Boolean", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 213 public volatile Object _boolean;
jlaskey@3 214
jlaskey@3 215 /** ECMA 15.1.4.6 - Number constructor */
jlaskey@3 216 @Property(name = "Number", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 217 public volatile Object number;
jlaskey@3 218
jlaskey@3 219 /** ECMA 15.1.4.7 Date constructor */
jlaskey@3 220 @Property(name = "Date", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 221 public volatile Object date;
jlaskey@3 222
jlaskey@3 223 /** ECMA 15.1.4.8 RegExp constructor */
jlaskey@3 224 @Property(name = "RegExp", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 225 public volatile Object regexp;
jlaskey@3 226
jlaskey@3 227 /** ECMA 15.12 - The JSON object */
jlaskey@3 228 @Property(name = "JSON", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 229 public volatile Object json;
jlaskey@3 230
jlaskey@3 231 /** Nashorn extension: global.JSAdapter */
jlaskey@3 232 @Property(name = "JSAdapter", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 233 public volatile Object jsadapter;
jlaskey@3 234
jlaskey@3 235 /** ECMA 15.8 - The Math object */
jlaskey@3 236 @Property(name = "Math", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 237 public volatile Object math;
jlaskey@3 238
jlaskey@3 239 /** Error object */
jlaskey@3 240 @Property(name = "Error", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 241 public volatile Object error;
jlaskey@3 242
jlaskey@3 243 /** EvalError object */
jlaskey@3 244 @Property(name = "EvalError", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 245 public volatile Object evalError;
jlaskey@3 246
jlaskey@3 247 /** RangeError object */
jlaskey@3 248 @Property(name = "RangeError", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 249 public volatile Object rangeError;
jlaskey@3 250
jlaskey@3 251 /** ReferenceError object */
jlaskey@3 252 @Property(name = "ReferenceError", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 253 public volatile Object referenceError;
jlaskey@3 254
jlaskey@3 255 /** SyntaxError object */
jlaskey@3 256 @Property(name = "SyntaxError", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 257 public volatile Object syntaxError;
jlaskey@3 258
jlaskey@3 259 /** TypeError object */
jlaskey@3 260 @Property(name = "TypeError", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 261 public volatile Object typeError;
jlaskey@3 262
jlaskey@3 263 /** URIError object */
jlaskey@3 264 @Property(name = "URIError", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 265 public volatile Object uriError;
jlaskey@3 266
jlaskey@3 267 /** ArrayBuffer object */
jlaskey@3 268 @Property(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 269 public volatile Object arrayBuffer;
jlaskey@3 270
sundar@770 271 /** DataView object */
sundar@770 272 @Property(name = "DataView", attributes = Attribute.NOT_ENUMERABLE)
sundar@770 273 public volatile Object dataView;
sundar@770 274
jlaskey@3 275 /** TypedArray (int8) */
jlaskey@3 276 @Property(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 277 public volatile Object int8Array;
jlaskey@3 278
jlaskey@3 279 /** TypedArray (uint8) */
jlaskey@3 280 @Property(name = "Uint8Array", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 281 public volatile Object uint8Array;
jlaskey@3 282
jlaskey@3 283 /** TypedArray (uint8) - Clamped */
jlaskey@3 284 @Property(name = "Uint8ClampedArray", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 285 public volatile Object uint8ClampedArray;
jlaskey@3 286
jlaskey@3 287 /** TypedArray (int16) */
jlaskey@3 288 @Property(name = "Int16Array", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 289 public volatile Object int16Array;
jlaskey@3 290
jlaskey@3 291 /** TypedArray (uint16) */
jlaskey@3 292 @Property(name = "Uint16Array", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 293 public volatile Object uint16Array;
jlaskey@3 294
jlaskey@3 295 /** TypedArray (int32) */
jlaskey@3 296 @Property(name = "Int32Array", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 297 public volatile Object int32Array;
jlaskey@3 298
jlaskey@3 299 /** TypedArray (uint32) */
jlaskey@3 300 @Property(name = "Uint32Array", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 301 public volatile Object uint32Array;
jlaskey@3 302
jlaskey@3 303 /** TypedArray (float32) */
jlaskey@3 304 @Property(name = "Float32Array", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 305 public volatile Object float32Array;
jlaskey@3 306
jlaskey@3 307 /** TypedArray (float64) */
jlaskey@3 308 @Property(name = "Float64Array", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 309 public volatile Object float64Array;
jlaskey@3 310
jlaskey@3 311 /** Nashorn extension: Java access - global.Packages */
jlaskey@3 312 @Property(name = "Packages", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 313 public volatile Object packages;
jlaskey@3 314
sundar@146 315 /** Nashorn extension: Java access - global.com */
sundar@146 316 @Property(attributes = Attribute.NOT_ENUMERABLE)
sundar@146 317 public volatile Object com;
sundar@146 318
sundar@146 319 /** Nashorn extension: Java access - global.edu */
sundar@146 320 @Property(attributes = Attribute.NOT_ENUMERABLE)
sundar@146 321 public volatile Object edu;
sundar@146 322
jlaskey@3 323 /** Nashorn extension: Java access - global.java */
jlaskey@3 324 @Property(attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 325 public volatile Object java;
jlaskey@3 326
sundar@146 327 /** Nashorn extension: Java access - global.javafx */
sundar@146 328 @Property(attributes = Attribute.NOT_ENUMERABLE)
sundar@146 329 public volatile Object javafx;
sundar@146 330
jlaskey@3 331 /** Nashorn extension: Java access - global.javax */
jlaskey@3 332 @Property(attributes = Attribute.NOT_ENUMERABLE)
sundar@146 333 public volatile Object javax;
sundar@146 334
sundar@146 335 /** Nashorn extension: Java access - global.org */
sundar@146 336 @Property(attributes = Attribute.NOT_ENUMERABLE)
sundar@146 337 public volatile Object org;
jlaskey@3 338
jlaskey@3 339 /** Nashorn extension: Java access - global.javaImporter */
jlaskey@3 340 @Property(name = "JavaImporter", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 341 public volatile Object javaImporter;
jlaskey@3 342
jlaskey@3 343 /** Nashorn extension: global.Java Object constructor. */
jlaskey@3 344 @Property(name = "Java", attributes = Attribute.NOT_ENUMERABLE)
jlaskey@3 345 public volatile Object javaApi;
jlaskey@3 346
jlaskey@3 347 /** Nashorn extension: current script's file name */
jlaskey@3 348 @Property(name = "__FILE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
attila@963 349 public final Object __FILE__ = LOCATION_PROPERTY_PLACEHOLDER;
jlaskey@3 350
jlaskey@3 351 /** Nashorn extension: current script's directory */
jlaskey@3 352 @Property(name = "__DIR__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
attila@963 353 public final Object __DIR__ = LOCATION_PROPERTY_PLACEHOLDER;
jlaskey@3 354
jlaskey@3 355 /** Nashorn extension: current source line number being executed */
jlaskey@3 356 @Property(name = "__LINE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
attila@963 357 public final Object __LINE__ = LOCATION_PROPERTY_PLACEHOLDER;
jlaskey@3 358
jlaskey@3 359 /** Used as Date.prototype's default value */
jlaskey@3 360 public NativeDate DEFAULT_DATE;
jlaskey@3 361
jlaskey@3 362 /** Used as RegExp.prototype's default value */
jlaskey@3 363 public NativeRegExp DEFAULT_REGEXP;
jlaskey@3 364
jlaskey@3 365 /*
jlaskey@3 366 * Built-in constructor objects: Even if user changes dynamic values of
jlaskey@3 367 * "Object", "Array" etc., we still want to keep original values of these
jlaskey@3 368 * constructors here. For example, we need to be able to create array,
jlaskey@3 369 * regexp literals even after user overwrites global "Array" or "RegExp"
jlaskey@3 370 * constructor - see also ECMA 262 spec. Annex D.
jlaskey@3 371 */
jlaskey@3 372 private ScriptFunction builtinFunction;
jlaskey@3 373 private ScriptFunction builtinObject;
jlaskey@3 374 private ScriptFunction builtinArray;
jlaskey@3 375 private ScriptFunction builtinBoolean;
jlaskey@3 376 private ScriptFunction builtinDate;
jlaskey@3 377 private ScriptObject builtinJSON;
jlaskey@3 378 private ScriptFunction builtinJSAdapter;
jlaskey@3 379 private ScriptObject builtinMath;
jlaskey@3 380 private ScriptFunction builtinNumber;
jlaskey@3 381 private ScriptFunction builtinRegExp;
jlaskey@3 382 private ScriptFunction builtinString;
jlaskey@3 383 private ScriptFunction builtinError;
jlaskey@3 384 private ScriptFunction builtinEval;
jlaskey@3 385 private ScriptFunction builtinEvalError;
jlaskey@3 386 private ScriptFunction builtinRangeError;
jlaskey@3 387 private ScriptFunction builtinReferenceError;
jlaskey@3 388 private ScriptFunction builtinSyntaxError;
jlaskey@3 389 private ScriptFunction builtinTypeError;
jlaskey@3 390 private ScriptFunction builtinURIError;
jlaskey@3 391 private ScriptObject builtinPackages;
sundar@146 392 private ScriptObject builtinCom;
sundar@146 393 private ScriptObject builtinEdu;
jlaskey@3 394 private ScriptObject builtinJava;
sundar@146 395 private ScriptObject builtinJavafx;
jlaskey@3 396 private ScriptObject builtinJavax;
sundar@146 397 private ScriptObject builtinOrg;
attila@963 398 private ScriptFunction builtinJavaImporter;
jlaskey@3 399 private ScriptObject builtinJavaApi;
attila@963 400 private ScriptFunction builtinArrayBuffer;
attila@963 401 private ScriptFunction builtinDataView;
attila@963 402 private ScriptFunction builtinInt8Array;
attila@963 403 private ScriptFunction builtinUint8Array;
attila@963 404 private ScriptFunction builtinUint8ClampedArray;
attila@963 405 private ScriptFunction builtinInt16Array;
attila@963 406 private ScriptFunction builtinUint16Array;
attila@963 407 private ScriptFunction builtinInt32Array;
attila@963 408 private ScriptFunction builtinUint32Array;
attila@963 409 private ScriptFunction builtinFloat32Array;
attila@963 410 private ScriptFunction builtinFloat64Array;
jlaskey@3 411
sundar@690 412 /*
sundar@690 413 * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
sundar@690 414 */
sundar@690 415 private ScriptFunction typeErrorThrower;
sundar@690 416
jlaskey@3 417 // Flag to indicate that a split method issued a return statement
jlaskey@3 418 private int splitState = -1;
jlaskey@3 419
hannesw@79 420 // Used to store the last RegExp result to support deprecated RegExp constructor properties
hannesw@114 421 private RegExpResult lastRegExpResult;
hannesw@79 422
attila@963 423 private static final MethodHandle EVAL = findOwnMH_S("eval", Object.class, Object.class, Object.class);
attila@963 424 private static final MethodHandle NO_SUCH_PROPERTY = findOwnMH_S(NO_SUCH_PROPERTY_NAME, Object.class, Object.class, Object.class);
attila@963 425 private static final MethodHandle PRINT = findOwnMH_S("print", Object.class, Object.class, Object[].class);
attila@963 426 private static final MethodHandle PRINTLN = findOwnMH_S("println", Object.class, Object.class, Object[].class);
attila@963 427 private static final MethodHandle LOAD = findOwnMH_S("load", Object.class, Object.class, Object.class);
attila@963 428 private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH_S("loadWithNewGlobal", Object.class, Object.class, Object[].class);
attila@963 429 private static final MethodHandle EXIT = findOwnMH_S("exit", Object.class, Object.class, Object.class);
attila@963 430
attila@963 431 /** Invalidate a reserved name, such as "apply" or "call" if assigned */
attila@963 432 public MethodHandle INVALIDATE_RESERVED_NAME = MH.bindTo(findOwnMH_V("invalidateReservedName", void.class, String.class), this);
jlaskey@3 433
hannesw@380 434 // initialized by nasgen
hannesw@380 435 private static PropertyMap $nasgenmap$;
hannesw@380 436
sundar@541 437 // context to which this global belongs to
sundar@541 438 private final Context context;
sundar@541 439
attila@963 440 // current ScriptContext to use - can be null.
attila@963 441 private ScriptContext scontext;
attila@963 442 // associated Property object for "context" property.
attila@963 443 private jdk.nashorn.internal.runtime.Property scontextProperty;
attila@963 444
attila@963 445 /**
attila@963 446 * Set the current script context
attila@963 447 * @param scontext script context
attila@963 448 */
attila@963 449 public void setScriptContext(final ScriptContext scontext) {
attila@963 450 this.scontext = scontext;
attila@963 451 scontextProperty.setValue(this, this, scontext, false);
attila@963 452 }
attila@963 453
attila@963 454 // global constants for this global - they can be replaced with MethodHandle.constant until invalidated
attila@963 455 private static AtomicReference<GlobalConstants> gcsInstance = new AtomicReference<>();
attila@963 456
sundar@541 457 @Override
sundar@541 458 protected Context getContext() {
sundar@541 459 return context;
sundar@541 460 }
sundar@541 461
sundar@456 462 // performs initialization checks for Global constructor and returns the
sundar@456 463 // PropertyMap, if everything is fine.
sundar@456 464 private static PropertyMap checkAndGetMap(final Context context) {
sundar@456 465 // security check first
sundar@456 466 final SecurityManager sm = System.getSecurityManager();
sundar@456 467 if (sm != null) {
sundar@492 468 sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL));
sundar@456 469 }
sundar@456 470
sundar@456 471 // null check on context
sundar@456 472 context.getClass();
sundar@456 473
attila@963 474 return $nasgenmap$;
sundar@456 475 }
sundar@456 476
jlaskey@3 477 /**
jlaskey@3 478 * Constructor
lagergren@89 479 *
lagergren@89 480 * @param context the context
jlaskey@3 481 */
sundar@82 482 public Global(final Context context) {
sundar@456 483 super(checkAndGetMap(context));
sundar@541 484 this.context = context;
sundar@418 485 this.setIsScope();
attila@963 486 this.optimisticFunctionMap = new HashMap<>();
attila@963 487 //we can only share one instance of Global constants between globals, or we consume way too much
attila@963 488 //memory - this is good enough for most programs
attila@963 489 while (gcsInstance.get() == null) {
attila@963 490 gcsInstance.compareAndSet(null, new GlobalConstants(context.getLogger(GlobalConstants.class)));
attila@963 491 }
jlaskey@3 492 }
jlaskey@3 493
jlaskey@3 494 /**
sundar@82 495 * Script access to "current" Global instance
jlaskey@3 496 *
jlaskey@3 497 * @return the global singleton
jlaskey@3 498 */
jlaskey@3 499 public static Global instance() {
attila@962 500 final Global global = Context.getGlobal();
sundar@771 501 global.getClass(); // null check
sundar@771 502 return global;
jlaskey@3 503 }
jlaskey@3 504
attila@963 505 private static Global instanceFrom(final Object self) {
attila@963 506 return self instanceof Global? (Global)self : instance();
attila@963 507 }
attila@963 508
attila@963 509 /**
attila@963 510 * Return the global constants map for fields that
attila@963 511 * can be accessed as MethodHandle.constant
attila@963 512 * @return constant map
attila@963 513 */
attila@963 514 public static GlobalConstants getConstants() {
attila@963 515 return gcsInstance.get();
attila@963 516 }
attila@963 517
attila@963 518 /**
attila@963 519 * Check if we have a Global instance
attila@963 520 * @return true if one exists
attila@963 521 */
attila@963 522 public static boolean hasInstance() {
attila@963 523 return Context.getGlobal() != null;
attila@963 524 }
attila@963 525
jlaskey@3 526 /**
sundar@118 527 * Script access to {@link ScriptEnvironment}
sundar@118 528 *
sundar@118 529 * @return the script environment
sundar@118 530 */
sundar@118 531 static ScriptEnvironment getEnv() {
sundar@414 532 return instance().getContext().getEnv();
sundar@118 533 }
sundar@118 534
sundar@118 535 /**
jlaskey@3 536 * Script access to {@link Context}
jlaskey@3 537 *
jlaskey@3 538 * @return the context
jlaskey@3 539 */
sundar@41 540 static Context getThisContext() {
sundar@414 541 return instance().getContext();
jlaskey@3 542 }
jlaskey@3 543
sundar@771 544 // Runtime interface to Global
jlaskey@3 545
sundar@771 546 /**
sundar@964 547 * Is there a class filter in the current Context?
sundar@964 548 * @return class filter
sundar@964 549 */
sundar@964 550 public ClassFilter getClassFilter() {
sundar@964 551 return context.getClassFilter();
sundar@964 552 }
sundar@964 553
sundar@964 554 /**
sundar@771 555 * Is this global of the given Context?
sundar@771 556 * @param ctxt the context
sundar@771 557 * @return true if this global belongs to the given Context
sundar@771 558 */
lagergren@610 559 public boolean isOfContext(final Context ctxt) {
lagergren@610 560 return this.context == ctxt;
sundar@541 561 }
sundar@541 562
sundar@771 563 /**
sundar@771 564 * Does this global belong to a strict Context?
sundar@771 565 * @return true if this global belongs to a strict Context
sundar@771 566 */
sundar@541 567 public boolean isStrictContext() {
sundar@541 568 return context.getEnv()._strict;
sundar@541 569 }
sundar@541 570
sundar@771 571 /**
sundar@771 572 * Initialize standard builtin objects like "Object", "Array", "Function" etc.
sundar@771 573 * as well as our extension builtin objects like "Java", "JSAdapter" as properties
sundar@771 574 * of the global scope object.
attila@963 575 *
attila@963 576 * @param engine ScriptEngine to initialize
sundar@771 577 */
attila@963 578 public void initBuiltinObjects(final ScriptEngine engine) {
jlaskey@3 579 if (this.builtinObject != null) {
jlaskey@3 580 // already initialized, just return
jlaskey@3 581 return;
jlaskey@3 582 }
jlaskey@3 583
attila@963 584 init(engine);
jlaskey@3 585 }
jlaskey@3 586
sundar@771 587 /**
sundar@771 588 * Wrap a Java object as corresponding script object
sundar@771 589 *
sundar@771 590 * @param obj object to wrap
sundar@771 591 * @return wrapped object
sundar@771 592 */
jlaskey@3 593 public Object wrapAsObject(final Object obj) {
jlaskey@3 594 if (obj instanceof Boolean) {
sundar@414 595 return new NativeBoolean((Boolean)obj, this);
jlaskey@3 596 } else if (obj instanceof Number) {
sundar@414 597 return new NativeNumber(((Number)obj).doubleValue(), this);
jlaskey@3 598 } else if (obj instanceof String || obj instanceof ConsString) {
sundar@414 599 return new NativeString((CharSequence)obj, this);
jlaskey@3 600 } else if (obj instanceof Object[]) { // extension
jlaskey@3 601 return new NativeArray((Object[])obj);
jlaskey@3 602 } else if (obj instanceof double[]) { // extension
jlaskey@3 603 return new NativeArray((double[])obj);
jlaskey@3 604 } else if (obj instanceof long[]) {
jlaskey@3 605 return new NativeArray((long[])obj);
jlaskey@3 606 } else if (obj instanceof int[]) {
jlaskey@3 607 return new NativeArray((int[])obj);
jlaskey@3 608 } else {
jlaskey@3 609 // FIXME: more special cases? Map? List?
jlaskey@3 610 return obj;
jlaskey@3 611 }
jlaskey@3 612 }
jlaskey@3 613
sundar@771 614 /**
sundar@771 615 * Lookup helper for JS primitive types
sundar@771 616 *
sundar@771 617 * @param request the link request for the dynamic call site.
sundar@771 618 * @param self self reference
sundar@771 619 *
sundar@771 620 * @return guarded invocation
sundar@771 621 */
attila@963 622 public static GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
hannesw@51 623 if (self instanceof String || self instanceof ConsString) {
hannesw@51 624 return NativeString.lookupPrimitive(request, self);
hannesw@51 625 } else if (self instanceof Number) {
hannesw@51 626 return NativeNumber.lookupPrimitive(request, self);
hannesw@51 627 } else if (self instanceof Boolean) {
hannesw@51 628 return NativeBoolean.lookupPrimitive(request, self);
hannesw@51 629 }
hannesw@51 630 throw new IllegalArgumentException("Unsupported primitive: " + self);
jlaskey@3 631 }
jlaskey@3 632
sundar@771 633 /**
sundar@771 634 * Create a new empty script object
sundar@771 635 *
sundar@771 636 * @return the new ScriptObject
sundar@771 637 */
jlaskey@3 638 public ScriptObject newObject() {
hannesw@766 639 return new JO(getObjectPrototype(), JO.getInitialMap());
jlaskey@3 640 }
jlaskey@3 641
sundar@771 642 /**
sundar@771 643 * Default value of given type
sundar@771 644 *
sundar@771 645 * @param sobj script object
sundar@771 646 * @param typeHint type hint
sundar@771 647 *
sundar@771 648 * @return default value
sundar@771 649 */
jlaskey@3 650 public Object getDefaultValue(final ScriptObject sobj, final Class<?> typeHint) {
jlaskey@3 651 // When the [[DefaultValue]] internal method of O is called with no hint,
jlaskey@3 652 // then it behaves as if the hint were Number, unless O is a Date object
jlaskey@3 653 // in which case it behaves as if the hint were String.
jlaskey@3 654 Class<?> hint = typeHint;
jlaskey@3 655 if (hint == null) {
jlaskey@3 656 hint = Number.class;
jlaskey@3 657 }
jlaskey@3 658
jlaskey@3 659 try {
jlaskey@3 660 if (hint == String.class) {
jlaskey@3 661
jlaskey@3 662 final Object toString = TO_STRING.getGetter().invokeExact(sobj);
sundar@459 663
sundar@459 664 if (Bootstrap.isCallable(toString)) {
jlaskey@3 665 final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
jlaskey@3 666 if (JSType.isPrimitive(value)) {
jlaskey@3 667 return value;
jlaskey@3 668 }
jlaskey@3 669 }
jlaskey@3 670
jlaskey@3 671 final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
sundar@459 672 if (Bootstrap.isCallable(valueOf)) {
jlaskey@3 673 final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
jlaskey@3 674 if (JSType.isPrimitive(value)) {
jlaskey@3 675 return value;
jlaskey@3 676 }
jlaskey@3 677 }
lagergren@112 678 throw typeError(this, "cannot.get.default.string");
jlaskey@3 679 }
jlaskey@3 680
jlaskey@3 681 if (hint == Number.class) {
jlaskey@3 682 final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
sundar@459 683 if (Bootstrap.isCallable(valueOf)) {
jlaskey@3 684 final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
jlaskey@3 685 if (JSType.isPrimitive(value)) {
jlaskey@3 686 return value;
jlaskey@3 687 }
jlaskey@3 688 }
jlaskey@3 689
jlaskey@3 690 final Object toString = TO_STRING.getGetter().invokeExact(sobj);
sundar@459 691 if (Bootstrap.isCallable(toString)) {
jlaskey@3 692 final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
jlaskey@3 693 if (JSType.isPrimitive(value)) {
jlaskey@3 694 return value;
jlaskey@3 695 }
jlaskey@3 696 }
jlaskey@3 697
lagergren@112 698 throw typeError(this, "cannot.get.default.number");
jlaskey@3 699 }
jlaskey@3 700 } catch (final RuntimeException | Error e) {
jlaskey@3 701 throw e;
jlaskey@3 702 } catch (final Throwable t) {
jlaskey@3 703 throw new RuntimeException(t);
jlaskey@3 704 }
jlaskey@3 705
jlaskey@3 706 return UNDEFINED;
jlaskey@3 707 }
jlaskey@3 708
sundar@771 709 /**
sundar@771 710 * Is the given ScriptObject an ECMAScript Error object?
sundar@771 711 *
sundar@771 712 * @param sobj the object being checked
sundar@771 713 * @return true if sobj is an Error object
sundar@771 714 */
jlaskey@3 715 public boolean isError(final ScriptObject sobj) {
jlaskey@3 716 final ScriptObject errorProto = getErrorPrototype();
jlaskey@3 717 ScriptObject proto = sobj.getProto();
jlaskey@3 718 while (proto != null) {
jlaskey@3 719 if (proto == errorProto) {
jlaskey@3 720 return true;
jlaskey@3 721 }
jlaskey@3 722 proto = proto.getProto();
jlaskey@3 723 }
jlaskey@3 724 return false;
jlaskey@3 725 }
jlaskey@3 726
sundar@771 727 /**
sundar@771 728 * Create a new ECMAScript Error object.
sundar@771 729 *
sundar@771 730 * @param msg error message
sundar@771 731 * @return newly created Error object
sundar@771 732 */
jlaskey@3 733 public ScriptObject newError(final String msg) {
sundar@414 734 return new NativeError(msg, this);
jlaskey@3 735 }
jlaskey@3 736
sundar@771 737 /**
sundar@771 738 * Create a new ECMAScript EvalError object.
sundar@771 739 *
sundar@771 740 * @param msg error message
sundar@771 741 * @return newly created EvalError object
sundar@771 742 */
jlaskey@3 743 public ScriptObject newEvalError(final String msg) {
sundar@414 744 return new NativeEvalError(msg, this);
jlaskey@3 745 }
jlaskey@3 746
sundar@771 747 /**
sundar@771 748 * Create a new ECMAScript RangeError object.
sundar@771 749 *
sundar@771 750 * @param msg error message
sundar@771 751 * @return newly created RangeError object
sundar@771 752 */
jlaskey@3 753 public ScriptObject newRangeError(final String msg) {
sundar@414 754 return new NativeRangeError(msg, this);
jlaskey@3 755 }
jlaskey@3 756
sundar@771 757 /**
sundar@771 758 * Create a new ECMAScript ReferenceError object.
sundar@771 759 *
sundar@771 760 * @param msg error message
sundar@771 761 * @return newly created ReferenceError object
sundar@771 762 */
jlaskey@3 763 public ScriptObject newReferenceError(final String msg) {
sundar@414 764 return new NativeReferenceError(msg, this);
jlaskey@3 765 }
jlaskey@3 766
sundar@771 767 /**
sundar@771 768 * Create a new ECMAScript SyntaxError object.
sundar@771 769 *
sundar@771 770 * @param msg error message
sundar@771 771 * @return newly created SyntaxError object
sundar@771 772 */
jlaskey@3 773 public ScriptObject newSyntaxError(final String msg) {
sundar@414 774 return new NativeSyntaxError(msg, this);
jlaskey@3 775 }
jlaskey@3 776
sundar@771 777 /**
sundar@771 778 * Create a new ECMAScript TypeError object.
sundar@771 779 *
sundar@771 780 * @param msg error message
sundar@771 781 * @return newly created TypeError object
sundar@771 782 */
jlaskey@3 783 public ScriptObject newTypeError(final String msg) {
sundar@414 784 return new NativeTypeError(msg, this);
jlaskey@3 785 }
jlaskey@3 786
sundar@771 787 /**
sundar@771 788 * Create a new ECMAScript URIError object.
sundar@771 789 *
sundar@771 790 * @param msg error message
sundar@771 791 * @return newly created URIError object
sundar@771 792 */
jlaskey@3 793 public ScriptObject newURIError(final String msg) {
sundar@414 794 return new NativeURIError(msg, this);
jlaskey@3 795 }
jlaskey@3 796
sundar@771 797 /**
sundar@771 798 * Create a new ECMAScript GenericDescriptor object.
sundar@771 799 *
sundar@771 800 * @param configurable is the property configurable?
sundar@771 801 * @param enumerable is the property enumerable?
sundar@771 802 * @return newly created GenericDescriptor object
sundar@771 803 */
jlaskey@3 804 public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
sundar@414 805 return new GenericPropertyDescriptor(configurable, enumerable, this);
jlaskey@3 806 }
jlaskey@3 807
sundar@771 808 /**
sundar@771 809 * Create a new ECMAScript DatePropertyDescriptor object.
sundar@771 810 *
sundar@771 811 * @param value of the data property
sundar@771 812 * @param configurable is the property configurable?
sundar@771 813 * @param enumerable is the property enumerable?
attila@963 814 * @param writable is the property writable?
sundar@771 815 * @return newly created DataPropertyDescriptor object
sundar@771 816 */
jlaskey@3 817 public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
sundar@414 818 return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
jlaskey@3 819 }
jlaskey@3 820
sundar@771 821 /**
sundar@771 822 * Create a new ECMAScript AccessorPropertyDescriptor object.
sundar@771 823 *
sundar@771 824 * @param get getter function of the user accessor property
sundar@771 825 * @param set setter function of the user accessor property
sundar@771 826 * @param configurable is the property configurable?
sundar@771 827 * @param enumerable is the property enumerable?
sundar@771 828 * @return newly created AccessorPropertyDescriptor object
sundar@771 829 */
jlaskey@3 830 public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
sundar@414 831 final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set, this);
jlaskey@3 832
jlaskey@3 833 if (get == null) {
sundar@344 834 desc.delete(PropertyDescriptor.GET, false);
jlaskey@3 835 }
jlaskey@3 836
jlaskey@3 837 if (set == null) {
sundar@344 838 desc.delete(PropertyDescriptor.SET, false);
jlaskey@3 839 }
jlaskey@3 840
jlaskey@3 841 return desc;
jlaskey@3 842 }
jlaskey@3 843
sundar@489 844 private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
sundar@489 845 final T obj = map.get(key);
sundar@489 846 if (obj != null) {
sundar@489 847 return obj;
sundar@489 848 }
sundar@489 849
sundar@489 850 try {
sundar@489 851 final T newObj = creator.call();
sundar@489 852 final T existingObj = map.putIfAbsent(key, newObj);
sundar@489 853 return existingObj != null ? existingObj : newObj;
sundar@489 854 } catch (final Exception exp) {
sundar@489 855 throw new RuntimeException(exp);
sundar@489 856 }
sundar@489 857 }
sundar@489 858
sundar@489 859 private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();
sundar@489 860
sundar@771 861
sundar@771 862 /**
sundar@771 863 * Get cached InvokeByName object for the given key
sundar@771 864 * @param key key to be associated with InvokeByName object
sundar@771 865 * @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
sundar@771 866 * @return InvokeByName object associated with the key.
sundar@771 867 */
sundar@489 868 public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
sundar@489 869 return getLazilyCreatedValue(key, creator, namedInvokers);
sundar@489 870 }
sundar@489 871
sundar@489 872 private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();
sundar@489 873
sundar@771 874 /**
sundar@771 875 * Get cached dynamic method handle for the given key
sundar@771 876 * @param key key to be associated with dynamic method handle
sundar@771 877 * @param creator if method handle is absent 'creator' is called to make one (lazy init)
sundar@771 878 * @return dynamic method handle associated with the key.
sundar@771 879 */
sundar@489 880 public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
sundar@489 881 return getLazilyCreatedValue(key, creator, dynamicInvokers);
sundar@489 882 }
sundar@489 883
jlaskey@3 884 /**
attila@963 885 * Hook to search missing variables in ScriptContext if available
attila@963 886 * @param self used to detect if scope call or not (this function is 'strict')
attila@963 887 * @param name name of the variable missing
attila@963 888 * @return value of the missing variable or undefined (or TypeError for scope search)
attila@963 889 */
attila@963 890 public static Object __noSuchProperty__(final Object self, final Object name) {
attila@963 891 final Global global = Global.instance();
attila@963 892 final ScriptContext sctxt = global.scontext;
attila@963 893 final String nameStr = name.toString();
attila@963 894
attila@963 895 if (sctxt != null) {
attila@963 896 final int scope = sctxt.getAttributesScope(nameStr);
attila@963 897 if (scope != -1) {
attila@963 898 return ScriptObjectMirror.unwrap(sctxt.getAttribute(nameStr, scope), global);
attila@963 899 }
attila@963 900 }
attila@963 901
attila@963 902 if (self == UNDEFINED) {
attila@963 903 // scope access and so throw ReferenceError
attila@963 904 throw referenceError(global, "not.defined", nameStr);
attila@963 905 }
attila@963 906
attila@963 907 return UNDEFINED;
attila@963 908 }
attila@963 909
attila@963 910 /**
jlaskey@3 911 * This is the eval used when 'indirect' eval call is made.
jlaskey@3 912 *
jlaskey@3 913 * var global = this;
jlaskey@3 914 * global.eval("print('hello')");
jlaskey@3 915 *
jlaskey@3 916 * @param self eval scope
jlaskey@3 917 * @param str eval string
jlaskey@3 918 *
jlaskey@3 919 * @return the result of eval
jlaskey@3 920 */
jlaskey@3 921 public static Object eval(final Object self, final Object str) {
attila@963 922 return directEval(self, str, UNDEFINED, UNDEFINED, false);
jlaskey@3 923 }
jlaskey@3 924
jlaskey@3 925 /**
jlaskey@3 926 * Direct eval
jlaskey@3 927 *
jlaskey@3 928 * @param self The scope of eval passed as 'self'
jlaskey@3 929 * @param str Evaluated code
jlaskey@3 930 * @param callThis "this" to be passed to the evaluated code
jlaskey@3 931 * @param location location of the eval call
jlaskey@3 932 * @param strict is eval called a strict mode code?
jlaskey@3 933 *
jlaskey@3 934 * @return the return value of the eval
jlaskey@3 935 *
jlaskey@3 936 * This is directly invoked from generated when eval(code) is called in user code
jlaskey@3 937 */
attila@963 938 public static Object directEval(final Object self, final Object str, final Object callThis, final Object location, final boolean strict) {
jlaskey@3 939 if (!(str instanceof String || str instanceof ConsString)) {
jlaskey@3 940 return str;
jlaskey@3 941 }
attila@963 942 final Global global = Global.instanceFrom(self);
attila@963 943 final ScriptObject scope = self instanceof ScriptObject ? (ScriptObject)self : global;
jlaskey@3 944
attila@963 945 return global.getContext().eval(scope, str.toString(), callThis, location, strict, true);
jlaskey@3 946 }
jlaskey@3 947
jlaskey@3 948 /**
jlaskey@3 949 * Global print implementation - Nashorn extension
jlaskey@3 950 *
jlaskey@3 951 * @param self scope
jlaskey@3 952 * @param objects arguments to print
jlaskey@3 953 *
jlaskey@3 954 * @return result of print (undefined)
jlaskey@3 955 */
jlaskey@3 956 public static Object print(final Object self, final Object... objects) {
attila@963 957 return Global.instanceFrom(self).printImpl(false, objects);
jlaskey@3 958 }
jlaskey@3 959
jlaskey@3 960 /**
jlaskey@3 961 * Global println implementation - Nashorn extension
jlaskey@3 962 *
jlaskey@3 963 * @param self scope
jlaskey@3 964 * @param objects arguments to print
jlaskey@3 965 *
jlaskey@3 966 * @return result of println (undefined)
jlaskey@3 967 */
jlaskey@3 968 public static Object println(final Object self, final Object... objects) {
attila@963 969 return Global.instanceFrom(self).printImpl(true, objects);
jlaskey@3 970 }
jlaskey@3 971
jlaskey@3 972 /**
jlaskey@3 973 * Global load implementation - Nashorn extension
jlaskey@3 974 *
jlaskey@3 975 * @param self scope
jlaskey@3 976 * @param source source to load
jlaskey@3 977 *
jlaskey@3 978 * @return result of load (undefined)
jlaskey@3 979 *
jlaskey@3 980 * @throws IOException if source could not be read
jlaskey@3 981 */
jlaskey@3 982 public static Object load(final Object self, final Object source) throws IOException {
attila@963 983 final Global global = Global.instanceFrom(self);
attila@963 984 final ScriptObject scope = self instanceof ScriptObject ? (ScriptObject)self : global;
sundar@414 985 return global.getContext().load(scope, source);
jlaskey@3 986 }
jlaskey@3 987
jlaskey@75 988 /**
jlaskey@317 989 * Global loadWithNewGlobal implementation - Nashorn extension
jlaskey@317 990 *
jlaskey@342 991 * @param self scope
jlaskey@342 992 * @param args from plus (optional) arguments to be passed to the loaded script
jlaskey@317 993 *
jlaskey@342 994 * @return result of load (may be undefined)
jlaskey@317 995 *
jlaskey@317 996 * @throws IOException if source could not be read
jlaskey@317 997 */
jlaskey@342 998 public static Object loadWithNewGlobal(final Object self, final Object...args) throws IOException {
attila@963 999 final Global global = Global.instanceFrom(self);
jlaskey@342 1000 final int length = args.length;
jlaskey@342 1001 final boolean hasArgs = 0 < length;
jlaskey@342 1002 final Object from = hasArgs ? args[0] : UNDEFINED;
jlaskey@342 1003 final Object[] arguments = hasArgs ? Arrays.copyOfRange(args, 1, length) : args;
jlaskey@342 1004
sundar@414 1005 return global.getContext().loadWithNewGlobal(from, arguments);
jlaskey@317 1006 }
jlaskey@317 1007
jlaskey@317 1008 /**
jlaskey@75 1009 * Global exit and quit implementation - Nashorn extension: perform a {@code System.exit} call from the script
jlaskey@75 1010 *
jlaskey@75 1011 * @param self self reference
jlaskey@75 1012 * @param code exit code
jlaskey@75 1013 *
attila@963 1014 * @return undefined (will never be reached)
jlaskey@75 1015 */
jlaskey@75 1016 public static Object exit(final Object self, final Object code) {
jlaskey@75 1017 System.exit(JSType.toInt32(code));
jlaskey@75 1018 return UNDEFINED;
jlaskey@75 1019 }
jlaskey@75 1020
sundar@414 1021 // builtin prototype accessors
jlaskey@3 1022 ScriptObject getFunctionPrototype() {
jlaskey@3 1023 return ScriptFunction.getPrototype(builtinFunction);
jlaskey@3 1024 }
jlaskey@3 1025
jlaskey@3 1026 ScriptObject getObjectPrototype() {
jlaskey@3 1027 return ScriptFunction.getPrototype(builtinObject);
jlaskey@3 1028 }
jlaskey@3 1029
jlaskey@3 1030 ScriptObject getArrayPrototype() {
jlaskey@3 1031 return ScriptFunction.getPrototype(builtinArray);
jlaskey@3 1032 }
jlaskey@3 1033
jlaskey@3 1034 ScriptObject getBooleanPrototype() {
jlaskey@3 1035 return ScriptFunction.getPrototype(builtinBoolean);
jlaskey@3 1036 }
jlaskey@3 1037
jlaskey@3 1038 ScriptObject getNumberPrototype() {
jlaskey@3 1039 return ScriptFunction.getPrototype(builtinNumber);
jlaskey@3 1040 }
jlaskey@3 1041
jlaskey@3 1042 ScriptObject getDatePrototype() {
jlaskey@3 1043 return ScriptFunction.getPrototype(builtinDate);
jlaskey@3 1044 }
jlaskey@3 1045
jlaskey@3 1046 ScriptObject getRegExpPrototype() {
jlaskey@3 1047 return ScriptFunction.getPrototype(builtinRegExp);
jlaskey@3 1048 }
jlaskey@3 1049
jlaskey@3 1050 ScriptObject getStringPrototype() {
jlaskey@3 1051 return ScriptFunction.getPrototype(builtinString);
jlaskey@3 1052 }
jlaskey@3 1053
jlaskey@3 1054 ScriptObject getErrorPrototype() {
jlaskey@3 1055 return ScriptFunction.getPrototype(builtinError);
jlaskey@3 1056 }
jlaskey@3 1057
jlaskey@3 1058 ScriptObject getEvalErrorPrototype() {
jlaskey@3 1059 return ScriptFunction.getPrototype(builtinEvalError);
jlaskey@3 1060 }
jlaskey@3 1061
jlaskey@3 1062 ScriptObject getRangeErrorPrototype() {
jlaskey@3 1063 return ScriptFunction.getPrototype(builtinRangeError);
jlaskey@3 1064 }
jlaskey@3 1065
jlaskey@3 1066 ScriptObject getReferenceErrorPrototype() {
jlaskey@3 1067 return ScriptFunction.getPrototype(builtinReferenceError);
jlaskey@3 1068 }
jlaskey@3 1069
jlaskey@3 1070 ScriptObject getSyntaxErrorPrototype() {
jlaskey@3 1071 return ScriptFunction.getPrototype(builtinSyntaxError);
jlaskey@3 1072 }
jlaskey@3 1073
jlaskey@3 1074 ScriptObject getTypeErrorPrototype() {
jlaskey@3 1075 return ScriptFunction.getPrototype(builtinTypeError);
jlaskey@3 1076 }
jlaskey@3 1077
jlaskey@3 1078 ScriptObject getURIErrorPrototype() {
jlaskey@3 1079 return ScriptFunction.getPrototype(builtinURIError);
jlaskey@3 1080 }
jlaskey@3 1081
jlaskey@3 1082 ScriptObject getJavaImporterPrototype() {
jlaskey@3 1083 return ScriptFunction.getPrototype(builtinJavaImporter);
jlaskey@3 1084 }
jlaskey@3 1085
jlaskey@3 1086 ScriptObject getJSAdapterPrototype() {
jlaskey@3 1087 return ScriptFunction.getPrototype(builtinJSAdapter);
jlaskey@3 1088 }
jlaskey@3 1089
jlaskey@3 1090 ScriptObject getArrayBufferPrototype() {
jlaskey@3 1091 return ScriptFunction.getPrototype(builtinArrayBuffer);
jlaskey@3 1092 }
jlaskey@3 1093
sundar@770 1094 ScriptObject getDataViewPrototype() {
sundar@770 1095 return ScriptFunction.getPrototype(builtinDataView);
sundar@770 1096 }
sundar@770 1097
jlaskey@3 1098 ScriptObject getInt8ArrayPrototype() {
jlaskey@3 1099 return ScriptFunction.getPrototype(builtinInt8Array);
jlaskey@3 1100 }
jlaskey@3 1101
jlaskey@3 1102 ScriptObject getUint8ArrayPrototype() {
jlaskey@3 1103 return ScriptFunction.getPrototype(builtinUint8Array);
jlaskey@3 1104 }
jlaskey@3 1105
jlaskey@3 1106 ScriptObject getUint8ClampedArrayPrototype() {
jlaskey@3 1107 return ScriptFunction.getPrototype(builtinUint8ClampedArray);
jlaskey@3 1108 }
jlaskey@3 1109
jlaskey@3 1110 ScriptObject getInt16ArrayPrototype() {
jlaskey@3 1111 return ScriptFunction.getPrototype(builtinInt16Array);
jlaskey@3 1112 }
jlaskey@3 1113
jlaskey@3 1114 ScriptObject getUint16ArrayPrototype() {
jlaskey@3 1115 return ScriptFunction.getPrototype(builtinUint16Array);
jlaskey@3 1116 }
jlaskey@3 1117
jlaskey@3 1118 ScriptObject getInt32ArrayPrototype() {
jlaskey@3 1119 return ScriptFunction.getPrototype(builtinInt32Array);
jlaskey@3 1120 }
jlaskey@3 1121
jlaskey@3 1122 ScriptObject getUint32ArrayPrototype() {
jlaskey@3 1123 return ScriptFunction.getPrototype(builtinUint32Array);
jlaskey@3 1124 }
jlaskey@3 1125
jlaskey@3 1126 ScriptObject getFloat32ArrayPrototype() {
jlaskey@3 1127 return ScriptFunction.getPrototype(builtinFloat32Array);
jlaskey@3 1128 }
jlaskey@3 1129
jlaskey@3 1130 ScriptObject getFloat64ArrayPrototype() {
jlaskey@3 1131 return ScriptFunction.getPrototype(builtinFloat64Array);
jlaskey@3 1132 }
jlaskey@3 1133
jlaskey@3 1134 private ScriptFunction getBuiltinArray() {
jlaskey@3 1135 return builtinArray;
jlaskey@3 1136 }
jlaskey@3 1137
sundar@690 1138 ScriptFunction getTypeErrorThrower() {
sundar@690 1139 return typeErrorThrower;
sundar@690 1140 }
sundar@690 1141
jlaskey@3 1142 /**
jlaskey@3 1143 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1144 *
jlaskey@3 1145 * @return true if builtin array has not been overridden
jlaskey@3 1146 */
jlaskey@3 1147 public static boolean isBuiltinArray() {
jlaskey@3 1148 final Global instance = Global.instance();
jlaskey@3 1149 return instance.array == instance.getBuiltinArray();
jlaskey@3 1150 }
jlaskey@3 1151
jlaskey@3 1152 private ScriptFunction getBuiltinBoolean() {
jlaskey@3 1153 return builtinBoolean;
jlaskey@3 1154 }
jlaskey@3 1155
jlaskey@3 1156 /**
jlaskey@3 1157 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1158 *
jlaskey@3 1159 * @return true if builtin boolean has not been overridden
jlaskey@3 1160 */
jlaskey@3 1161 public static boolean isBuiltinBoolean() {
jlaskey@3 1162 final Global instance = Global.instance();
jlaskey@3 1163 return instance._boolean == instance.getBuiltinBoolean();
jlaskey@3 1164 }
jlaskey@3 1165
jlaskey@3 1166 private ScriptFunction getBuiltinDate() {
jlaskey@3 1167 return builtinDate;
jlaskey@3 1168 }
jlaskey@3 1169
jlaskey@3 1170 /**
jlaskey@3 1171 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1172 *
jlaskey@3 1173 * @return true if builtin date has not been overridden
jlaskey@3 1174 */
jlaskey@3 1175 public static boolean isBuiltinDate() {
jlaskey@3 1176 final Global instance = Global.instance();
jlaskey@3 1177 return instance.date == instance.getBuiltinDate();
jlaskey@3 1178 }
jlaskey@3 1179
jlaskey@3 1180 private ScriptFunction getBuiltinError() {
jlaskey@3 1181 return builtinError;
jlaskey@3 1182 }
jlaskey@3 1183
jlaskey@3 1184 /**
jlaskey@3 1185 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1186 *
jlaskey@3 1187 * @return true if builtin error has not been overridden
jlaskey@3 1188 */
jlaskey@3 1189 public static boolean isBuiltinError() {
jlaskey@3 1190 final Global instance = Global.instance();
jlaskey@3 1191 return instance.error == instance.getBuiltinError();
jlaskey@3 1192 }
jlaskey@3 1193
jlaskey@3 1194 private ScriptFunction getBuiltinEvalError() {
jlaskey@3 1195 return builtinEvalError;
jlaskey@3 1196 }
jlaskey@3 1197
jlaskey@3 1198 /**
jlaskey@3 1199 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1200 *
jlaskey@3 1201 * @return true if builtin eval error has not been overridden
jlaskey@3 1202 */
jlaskey@3 1203 public static boolean isBuiltinEvalError() {
jlaskey@3 1204 final Global instance = Global.instance();
jlaskey@3 1205 return instance.evalError == instance.getBuiltinEvalError();
jlaskey@3 1206 }
jlaskey@3 1207
jlaskey@3 1208 private ScriptFunction getBuiltinFunction() {
jlaskey@3 1209 return builtinFunction;
jlaskey@3 1210 }
jlaskey@3 1211
jlaskey@3 1212 /**
jlaskey@3 1213 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1214 *
jlaskey@3 1215 * @return true if builtin function has not been overridden
jlaskey@3 1216 */
jlaskey@3 1217 public static boolean isBuiltinFunction() {
jlaskey@3 1218 final Global instance = Global.instance();
jlaskey@3 1219 return instance.function == instance.getBuiltinFunction();
jlaskey@3 1220 }
jlaskey@3 1221
jlaskey@3 1222 private ScriptFunction getBuiltinJSAdapter() {
jlaskey@3 1223 return builtinJSAdapter;
jlaskey@3 1224 }
jlaskey@3 1225
jlaskey@3 1226 /**
jlaskey@3 1227 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1228 *
jlaskey@3 1229 * @return true if builtin JSAdapter has not been overridden
jlaskey@3 1230 */
jlaskey@3 1231 public static boolean isBuiltinJSAdapter() {
jlaskey@3 1232 final Global instance = Global.instance();
jlaskey@3 1233 return instance.jsadapter == instance.getBuiltinJSAdapter();
jlaskey@3 1234 }
jlaskey@3 1235
jlaskey@3 1236 private ScriptObject getBuiltinJSON() {
jlaskey@3 1237 return builtinJSON;
jlaskey@3 1238 }
jlaskey@3 1239
jlaskey@3 1240 /**
jlaskey@3 1241 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1242 *
jlaskey@3 1243 * @return true if builtin JSON has has not been overridden
jlaskey@3 1244 */
jlaskey@3 1245 public static boolean isBuiltinJSON() {
jlaskey@3 1246 final Global instance = Global.instance();
jlaskey@3 1247 return instance.json == instance.getBuiltinJSON();
jlaskey@3 1248 }
jlaskey@3 1249
jlaskey@3 1250 private ScriptObject getBuiltinJava() {
jlaskey@3 1251 return builtinJava;
jlaskey@3 1252 }
jlaskey@3 1253
jlaskey@3 1254 /**
jlaskey@3 1255 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1256 *
jlaskey@3 1257 * @return true if builtin Java has not been overridden
jlaskey@3 1258 */
jlaskey@3 1259 public static boolean isBuiltinJava() {
jlaskey@3 1260 final Global instance = Global.instance();
jlaskey@3 1261 return instance.java == instance.getBuiltinJava();
jlaskey@3 1262 }
jlaskey@3 1263
jlaskey@3 1264 private ScriptObject getBuiltinJavax() {
jlaskey@3 1265 return builtinJavax;
jlaskey@3 1266 }
jlaskey@3 1267
jlaskey@3 1268 /**
jlaskey@3 1269 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1270 *
jlaskey@3 1271 * @return true if builtin Javax has not been overridden
jlaskey@3 1272 */
jlaskey@3 1273 public static boolean isBuiltinJavax() {
jlaskey@3 1274 final Global instance = Global.instance();
jlaskey@3 1275 return instance.javax == instance.getBuiltinJavax();
jlaskey@3 1276 }
jlaskey@3 1277
jlaskey@3 1278 private ScriptObject getBuiltinJavaImporter() {
jlaskey@3 1279 return builtinJavaImporter;
jlaskey@3 1280 }
jlaskey@3 1281
jlaskey@3 1282 /**
jlaskey@3 1283 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1284 *
jlaskey@3 1285 * @return true if builtin Java importer has not been overridden
jlaskey@3 1286 */
jlaskey@3 1287 public static boolean isBuiltinJavaImporter() {
jlaskey@3 1288 final Global instance = Global.instance();
jlaskey@3 1289 return instance.javaImporter == instance.getBuiltinJavaImporter();
jlaskey@3 1290 }
jlaskey@3 1291
jlaskey@3 1292 private ScriptObject getBuiltinMath() {
jlaskey@3 1293 return builtinMath;
jlaskey@3 1294 }
jlaskey@3 1295
jlaskey@3 1296 /**
jlaskey@3 1297 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1298 *
jlaskey@3 1299 * @return true if builtin math has not been overridden
jlaskey@3 1300 */
jlaskey@3 1301 public static boolean isBuiltinMath() {
jlaskey@3 1302 final Global instance = Global.instance();
jlaskey@3 1303 return instance.math == instance.getBuiltinMath();
jlaskey@3 1304 }
jlaskey@3 1305
jlaskey@3 1306 private ScriptFunction getBuiltinNumber() {
jlaskey@3 1307 return builtinNumber;
jlaskey@3 1308 }
jlaskey@3 1309
jlaskey@3 1310 /**
jlaskey@3 1311 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1312 *
jlaskey@3 1313 * @return true if builtin number has not been overridden
jlaskey@3 1314 */
jlaskey@3 1315 public static boolean isBuiltinNumber() {
jlaskey@3 1316 final Global instance = Global.instance();
jlaskey@3 1317 return instance.number == instance.getBuiltinNumber();
jlaskey@3 1318 }
jlaskey@3 1319
jlaskey@3 1320 private ScriptFunction getBuiltinObject() {
jlaskey@3 1321 return builtinObject;
jlaskey@3 1322 }
jlaskey@3 1323
jlaskey@3 1324 /**
jlaskey@3 1325 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1326 *
jlaskey@3 1327 * @return true if builtin object has not been overridden
jlaskey@3 1328 */
jlaskey@3 1329 public static boolean isBuiltinObject() {
jlaskey@3 1330 final Global instance = Global.instance();
jlaskey@3 1331 return instance.object == instance.getBuiltinObject();
jlaskey@3 1332 }
jlaskey@3 1333
jlaskey@3 1334 private ScriptObject getBuiltinPackages() {
jlaskey@3 1335 return builtinPackages;
jlaskey@3 1336 }
jlaskey@3 1337
jlaskey@3 1338 /**
jlaskey@3 1339 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1340 *
jlaskey@3 1341 * @return true if builtin package has not been overridden
jlaskey@3 1342 */
jlaskey@3 1343 public static boolean isBuiltinPackages() {
jlaskey@3 1344 final Global instance = Global.instance();
jlaskey@3 1345 return instance.packages == instance.getBuiltinPackages();
jlaskey@3 1346 }
jlaskey@3 1347
jlaskey@3 1348 private ScriptFunction getBuiltinRangeError() {
jlaskey@3 1349 return builtinRangeError;
jlaskey@3 1350 }
jlaskey@3 1351
jlaskey@3 1352 /**
jlaskey@3 1353 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1354 *
jlaskey@3 1355 * @return true if builtin range error has not been overridden
jlaskey@3 1356 */
jlaskey@3 1357 public static boolean isBuiltinRangeError() {
jlaskey@3 1358 final Global instance = Global.instance();
jlaskey@3 1359 return instance.rangeError == instance.getBuiltinRangeError();
jlaskey@3 1360 }
jlaskey@3 1361
jlaskey@3 1362 private ScriptFunction getBuiltinReferenceError() {
jlaskey@3 1363 return builtinReferenceError;
jlaskey@3 1364 }
jlaskey@3 1365
jlaskey@3 1366 /**
jlaskey@3 1367 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1368 *
jlaskey@3 1369 * @return true if builtin reference error has not been overridden
jlaskey@3 1370 */
jlaskey@3 1371 public static boolean isBuiltinReferenceError() {
jlaskey@3 1372 final Global instance = Global.instance();
jlaskey@3 1373 return instance.referenceError == instance.getBuiltinReferenceError();
jlaskey@3 1374 }
jlaskey@3 1375
jlaskey@3 1376 private ScriptFunction getBuiltinRegExp() {
jlaskey@3 1377 return builtinRegExp;
jlaskey@3 1378 }
jlaskey@3 1379
jlaskey@3 1380 /**
jlaskey@3 1381 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1382 *
jlaskey@3 1383 * @return true if builtin regexp has not been overridden
jlaskey@3 1384 */
jlaskey@3 1385 public static boolean isBuiltinRegExp() {
jlaskey@3 1386 final Global instance = Global.instance();
jlaskey@3 1387 return instance.regexp == instance.getBuiltinRegExp();
jlaskey@3 1388 }
jlaskey@3 1389
jlaskey@3 1390 private ScriptFunction getBuiltinString() {
jlaskey@3 1391 return builtinString;
jlaskey@3 1392 }
jlaskey@3 1393
jlaskey@3 1394 /**
jlaskey@3 1395 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1396 *
jlaskey@3 1397 * @return true if builtin Java has not been overridden
jlaskey@3 1398 */
jlaskey@3 1399 public static boolean isBuiltinString() {
jlaskey@3 1400 final Global instance = Global.instance();
jlaskey@3 1401 return instance.string == instance.getBuiltinString();
jlaskey@3 1402 }
jlaskey@3 1403
jlaskey@3 1404 private ScriptFunction getBuiltinSyntaxError() {
jlaskey@3 1405 return builtinSyntaxError;
jlaskey@3 1406 }
jlaskey@3 1407
jlaskey@3 1408 /**
jlaskey@3 1409 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1410 *
jlaskey@3 1411 * @return true if builtin syntax error has not been overridden
jlaskey@3 1412 */
jlaskey@3 1413 public static boolean isBuiltinSyntaxError() {
jlaskey@3 1414 final Global instance = Global.instance();
jlaskey@3 1415 return instance.syntaxError == instance.getBuiltinSyntaxError();
jlaskey@3 1416 }
jlaskey@3 1417
jlaskey@3 1418 private ScriptFunction getBuiltinTypeError() {
jlaskey@3 1419 return builtinTypeError;
jlaskey@3 1420 }
jlaskey@3 1421
jlaskey@3 1422 /**
jlaskey@3 1423 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1424 *
jlaskey@3 1425 * @return true if builtin type error has not been overridden
jlaskey@3 1426 */
jlaskey@3 1427 public static boolean isBuiltinTypeError() {
jlaskey@3 1428 final Global instance = Global.instance();
jlaskey@3 1429 return instance.typeError == instance.getBuiltinTypeError();
jlaskey@3 1430 }
jlaskey@3 1431
jlaskey@3 1432 private ScriptFunction getBuiltinURIError() {
jlaskey@3 1433 return builtinURIError;
jlaskey@3 1434 }
jlaskey@3 1435
jlaskey@3 1436 /**
jlaskey@3 1437 * Called from compiled script code to test if builtin has been overridden
jlaskey@3 1438 *
jlaskey@3 1439 * @return true if builtin URI error has not been overridden
jlaskey@3 1440 */
jlaskey@3 1441 public static boolean isBuiltinURIError() {
jlaskey@3 1442 final Global instance = Global.instance();
jlaskey@3 1443 return instance.uriError == instance.getBuiltinURIError();
jlaskey@3 1444 }
jlaskey@3 1445
jlaskey@3 1446 @Override
jlaskey@3 1447 public String getClassName() {
jlaskey@3 1448 return "global";
jlaskey@3 1449 }
jlaskey@3 1450
jlaskey@3 1451 /**
jlaskey@3 1452 * Copy function used to clone NativeRegExp objects.
jlaskey@3 1453 *
jlaskey@3 1454 * @param regexp a NativeRegExp to clone
jlaskey@3 1455 *
jlaskey@3 1456 * @return copy of the given regexp object
jlaskey@3 1457 */
jlaskey@3 1458 public static Object regExpCopy(final Object regexp) {
jlaskey@3 1459 return new NativeRegExp((NativeRegExp)regexp);
jlaskey@3 1460 }
jlaskey@3 1461
jlaskey@3 1462 /**
jlaskey@3 1463 * Convert given object to NativeRegExp type.
jlaskey@3 1464 *
jlaskey@3 1465 * @param obj object to be converted
jlaskey@3 1466 * @return NativeRegExp instance
jlaskey@3 1467 */
jlaskey@3 1468 public static NativeRegExp toRegExp(final Object obj) {
jlaskey@3 1469 if (obj instanceof NativeRegExp) {
jlaskey@3 1470 return (NativeRegExp)obj;
jlaskey@3 1471 }
jlaskey@3 1472 return new NativeRegExp(JSType.toString(obj));
jlaskey@3 1473 }
jlaskey@3 1474
jlaskey@3 1475 /**
jlaskey@3 1476 * ECMA 9.9 ToObject implementation
jlaskey@3 1477 *
jlaskey@3 1478 * @param obj an item for which to run ToObject
jlaskey@3 1479 * @return ToObject version of given item
jlaskey@3 1480 */
jlaskey@3 1481 public static Object toObject(final Object obj) {
jlaskey@3 1482 if (obj == null || obj == UNDEFINED) {
lagergren@112 1483 throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
jlaskey@3 1484 }
jlaskey@3 1485
jlaskey@3 1486 if (obj instanceof ScriptObject) {
jlaskey@3 1487 return obj;
jlaskey@3 1488 }
jlaskey@3 1489
jlaskey@3 1490 return instance().wrapAsObject(obj);
jlaskey@3 1491 }
jlaskey@3 1492
jlaskey@3 1493 /**
jlaskey@3 1494 * Allocate a new object array.
jlaskey@3 1495 *
jlaskey@3 1496 * @param initial object values.
jlaskey@3 1497 * @return the new array
jlaskey@3 1498 */
lagergren@66 1499 public static NativeArray allocate(final Object[] initial) {
hannesw@380 1500 ArrayData arrayData = ArrayData.allocate(initial);
hannesw@380 1501
hannesw@380 1502 for (int index = 0; index < initial.length; index++) {
hannesw@380 1503 final Object value = initial[index];
hannesw@380 1504
hannesw@380 1505 if (value == ScriptRuntime.EMPTY) {
hannesw@380 1506 arrayData = arrayData.delete(index);
hannesw@380 1507 }
hannesw@380 1508 }
hannesw@380 1509
hannesw@380 1510 return new NativeArray(arrayData);
jlaskey@3 1511 }
jlaskey@3 1512
jlaskey@3 1513 /**
jlaskey@3 1514 * Allocate a new number array.
jlaskey@3 1515 *
jlaskey@3 1516 * @param initial number values.
jlaskey@3 1517 * @return the new array
jlaskey@3 1518 */
lagergren@66 1519 public static NativeArray allocate(final double[] initial) {
hannesw@380 1520 return new NativeArray(ArrayData.allocate(initial));
jlaskey@3 1521 }
jlaskey@3 1522
jlaskey@3 1523 /**
jlaskey@3 1524 * Allocate a new long array.
jlaskey@3 1525 *
jlaskey@3 1526 * @param initial number values.
jlaskey@3 1527 * @return the new array
jlaskey@3 1528 */
lagergren@66 1529 public static NativeArray allocate(final long[] initial) {
hannesw@380 1530 return new NativeArray(ArrayData.allocate(initial));
jlaskey@3 1531 }
jlaskey@3 1532
jlaskey@3 1533 /**
jlaskey@3 1534 * Allocate a new integer array.
jlaskey@3 1535 *
jlaskey@3 1536 * @param initial number values.
jlaskey@3 1537 * @return the new array
jlaskey@3 1538 */
lagergren@66 1539 public static NativeArray allocate(final int[] initial) {
hannesw@380 1540 return new NativeArray(ArrayData.allocate(initial));
jlaskey@3 1541 }
jlaskey@3 1542
jlaskey@3 1543 /**
jlaskey@3 1544 * Allocate a new object array for arguments.
jlaskey@3 1545 *
jlaskey@3 1546 * @param arguments initial arguments passed.
jlaskey@3 1547 * @param callee reference to the function that uses arguments object
jlaskey@3 1548 * @param numParams actual number of declared parameters
jlaskey@3 1549 *
jlaskey@3 1550 * @return the new array
jlaskey@3 1551 */
attila@62 1552 public static ScriptObject allocateArguments(final Object[] arguments, final Object callee, final int numParams) {
jlaskey@3 1553 return NativeArguments.allocate(arguments, (ScriptFunction)callee, numParams);
jlaskey@3 1554 }
jlaskey@3 1555
jlaskey@3 1556 /**
jlaskey@3 1557 * Called from generated to check if given function is the builtin 'eval'. If
jlaskey@3 1558 * eval is used in a script, a lot of optimizations and assumptions cannot be done.
jlaskey@3 1559 *
jlaskey@3 1560 * @param fn function object that is checked
jlaskey@3 1561 * @return true if fn is the builtin eval
jlaskey@3 1562 */
jlaskey@3 1563 public static boolean isEval(final Object fn) {
jlaskey@3 1564 return fn == Global.instance().builtinEval;
jlaskey@3 1565 }
jlaskey@3 1566
jlaskey@3 1567 /**
attila@963 1568 * Called from generated to replace a location property placeholder with the actual location property value.
attila@963 1569 *
attila@963 1570 * @param placeholder the value tested for being a placeholder for a location property
attila@963 1571 * @param locationProperty the actual value for the location property
attila@963 1572 * @return locationProperty if placeholder is indeed a placeholder for a location property, the placeholder otherwise
attila@963 1573 */
attila@963 1574 public static Object replaceLocationPropertyPlaceholder(final Object placeholder, final Object locationProperty) {
attila@963 1575 return isLocationPropertyPlaceholder(placeholder) ? locationProperty : placeholder;
attila@963 1576 }
attila@963 1577
attila@963 1578 /**
attila@963 1579 * Called from runtime internals to check if the passed value is a location property placeholder.
attila@963 1580 * @param placeholder the value tested for being a placeholder for a location property
attila@963 1581 * @return true if the value is a placeholder, false otherwise.
attila@963 1582 */
attila@963 1583 public static boolean isLocationPropertyPlaceholder(final Object placeholder) {
attila@963 1584 return placeholder == LOCATION_PROPERTY_PLACEHOLDER;
attila@963 1585 }
attila@963 1586
attila@963 1587 /**
jlaskey@3 1588 * Create a new RegExp object.
jlaskey@3 1589 *
jlaskey@3 1590 * @param expression Regular expression.
jlaskey@3 1591 * @param options Search options.
jlaskey@3 1592 *
jlaskey@3 1593 * @return New RegExp object.
jlaskey@3 1594 */
jlaskey@3 1595 public static Object newRegExp(final String expression, final String options) {
jlaskey@3 1596 if (options == null) {
jlaskey@3 1597 return new NativeRegExp(expression);
jlaskey@3 1598 }
jlaskey@3 1599 return new NativeRegExp(expression, options);
jlaskey@3 1600 }
jlaskey@3 1601
jlaskey@3 1602 /**
jlaskey@3 1603 * Get the object prototype
jlaskey@3 1604 *
jlaskey@3 1605 * @return the object prototype
jlaskey@3 1606 */
jlaskey@3 1607 public static ScriptObject objectPrototype() {
jlaskey@3 1608 return Global.instance().getObjectPrototype();
jlaskey@3 1609 }
jlaskey@3 1610
jlaskey@3 1611 /**
jlaskey@3 1612 * Create a new empty object instance.
jlaskey@3 1613 *
jlaskey@3 1614 * @return New empty object.
jlaskey@3 1615 */
jlaskey@3 1616 public static ScriptObject newEmptyInstance() {
hannesw@380 1617 return Global.instance().newObject();
jlaskey@3 1618 }
jlaskey@3 1619
jlaskey@3 1620 /**
jlaskey@3 1621 * Check if a given object is a ScriptObject, raises an exception if this is
jlaskey@3 1622 * not the case
jlaskey@3 1623 *
jlaskey@3 1624 * @param obj and object to check
attila@963 1625 * @return the script object
jlaskey@3 1626 */
attila@963 1627 public static ScriptObject checkObject(final Object obj) {
jlaskey@3 1628 if (!(obj instanceof ScriptObject)) {
lagergren@112 1629 throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
jlaskey@3 1630 }
attila@963 1631 return (ScriptObject)obj;
jlaskey@3 1632 }
jlaskey@3 1633
jlaskey@3 1634 /**
jlaskey@3 1635 * ECMA 9.10 - implementation of CheckObjectCoercible, i.e. raise an exception
jlaskey@3 1636 * if this object is null or undefined.
jlaskey@3 1637 *
jlaskey@3 1638 * @param obj an object to check
jlaskey@3 1639 */
jlaskey@3 1640 public static void checkObjectCoercible(final Object obj) {
jlaskey@3 1641 if (obj == null || obj == UNDEFINED) {
lagergren@112 1642 throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
jlaskey@3 1643 }
jlaskey@3 1644 }
jlaskey@3 1645
jlaskey@3 1646 /**
jlaskey@3 1647 * Get the current split state.
jlaskey@3 1648 *
jlaskey@3 1649 * @return current split state
jlaskey@3 1650 */
jlaskey@3 1651 @Override
jlaskey@3 1652 public int getSplitState() {
jlaskey@3 1653 return splitState;
jlaskey@3 1654 }
jlaskey@3 1655
jlaskey@3 1656 /**
jlaskey@3 1657 * Set the current split state.
jlaskey@3 1658 *
jlaskey@3 1659 * @param state current split state
jlaskey@3 1660 */
jlaskey@3 1661 @Override
jlaskey@3 1662 public void setSplitState(final int state) {
jlaskey@3 1663 splitState = state;
jlaskey@3 1664 }
jlaskey@3 1665
attila@963 1666 private void init(final ScriptEngine engine) {
sundar@41 1667 assert Context.getGlobal() == this : "this global is not set as current";
sundar@41 1668
sundar@414 1669 final ScriptEnvironment env = getContext().getEnv();
sundar@414 1670
jlaskey@3 1671 // initialize Function and Object constructor
jlaskey@3 1672 initFunctionAndObject();
jlaskey@3 1673
jlaskey@3 1674 // Now fix Global's own proto.
hannesw@766 1675 this.setInitialProto(getObjectPrototype());
jlaskey@3 1676
jlaskey@3 1677 // initialize global function properties
jlaskey@3 1678 this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
jlaskey@3 1679
attila@963 1680 this.parseInt = ScriptFunctionImpl.makeFunction("parseInt", GlobalFunctions.PARSEINT,
attila@963 1681 new MethodHandle[] { GlobalFunctions.PARSEINT_OI, GlobalFunctions.PARSEINT_O });
jlaskey@3 1682 this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
jlaskey@3 1683 this.isNaN = ScriptFunctionImpl.makeFunction("isNaN", GlobalFunctions.IS_NAN);
jlaskey@3 1684 this.isFinite = ScriptFunctionImpl.makeFunction("isFinite", GlobalFunctions.IS_FINITE);
jlaskey@3 1685 this.encodeURI = ScriptFunctionImpl.makeFunction("encodeURI", GlobalFunctions.ENCODE_URI);
jlaskey@3 1686 this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
jlaskey@3 1687 this.decodeURI = ScriptFunctionImpl.makeFunction("decodeURI", GlobalFunctions.DECODE_URI);
jlaskey@3 1688 this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
jlaskey@3 1689 this.escape = ScriptFunctionImpl.makeFunction("escape", GlobalFunctions.ESCAPE);
jlaskey@3 1690 this.unescape = ScriptFunctionImpl.makeFunction("unescape", GlobalFunctions.UNESCAPE);
sundar@118 1691 this.print = ScriptFunctionImpl.makeFunction("print", env._print_no_newline ? PRINT : PRINTLN);
jlaskey@3 1692 this.load = ScriptFunctionImpl.makeFunction("load", LOAD);
jlaskey@317 1693 this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOADWITHNEWGLOBAL);
jlaskey@75 1694 this.exit = ScriptFunctionImpl.makeFunction("exit", EXIT);
jlaskey@75 1695 this.quit = ScriptFunctionImpl.makeFunction("quit", EXIT);
jlaskey@3 1696
jlaskey@3 1697 // built-in constructors
attila@963 1698 this.builtinArray = initConstructor("Array", ScriptFunction.class);
attila@963 1699 this.builtinBoolean = initConstructor("Boolean", ScriptFunction.class);
attila@963 1700 this.builtinDate = initConstructor("Date", ScriptFunction.class);
attila@963 1701 this.builtinJSON = initConstructor("JSON", ScriptObject.class);
attila@963 1702 this.builtinJSAdapter = initConstructor("JSAdapter", ScriptFunction.class);
attila@963 1703 this.builtinMath = initConstructor("Math", ScriptObject.class);
attila@963 1704 this.builtinNumber = initConstructor("Number", ScriptFunction.class);
attila@963 1705 this.builtinRegExp = initConstructor("RegExp", ScriptFunction.class);
attila@963 1706 this.builtinString = initConstructor("String", ScriptFunction.class);
jlaskey@3 1707
jlaskey@3 1708 // initialize String.prototype.length to 0
jlaskey@3 1709 // add String.prototype.length
jlaskey@3 1710 final ScriptObject stringPrototype = getStringPrototype();
jlaskey@3 1711 stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0);
jlaskey@3 1712
hannesw@634 1713 // set isArray flag on Array.prototype
jlaskey@3 1714 final ScriptObject arrayPrototype = getArrayPrototype();
hannesw@634 1715 arrayPrototype.setIsArray();
jlaskey@3 1716
sundar@414 1717 this.DEFAULT_DATE = new NativeDate(Double.NaN, this);
jlaskey@3 1718
jlaskey@3 1719 // initialize default regexp object
sundar@414 1720 this.DEFAULT_REGEXP = new NativeRegExp("(?:)", this);
jlaskey@3 1721
jlaskey@3 1722 // RegExp.prototype should behave like a RegExp object. So copy the
jlaskey@3 1723 // properties.
jlaskey@3 1724 final ScriptObject regExpProto = getRegExpPrototype();
jlaskey@3 1725 regExpProto.addBoundProperties(DEFAULT_REGEXP);
jlaskey@3 1726
jlaskey@3 1727 // Error stuff
jlaskey@3 1728 initErrorObjects();
jlaskey@3 1729
jlaskey@3 1730 // java access
sundar@418 1731 if (! env._no_java) {
sundar@418 1732 initJavaAccess();
sundar@418 1733 }
jlaskey@3 1734
sundar@418 1735 if (! env._no_typed_arrays) {
sundar@418 1736 initTypedArray();
sundar@418 1737 }
jlaskey@3 1738
sundar@118 1739 if (env._scripting) {
sundar@418 1740 initScripting(env);
jlaskey@3 1741 }
jlaskey@3 1742
sundar@760 1743 if (Context.DEBUG) {
sundar@760 1744 boolean debugOkay;
sundar@760 1745 final SecurityManager sm = System.getSecurityManager();
sundar@760 1746 if (sm != null) {
sundar@760 1747 try {
sundar@760 1748 sm.checkPermission(new RuntimePermission(Context.NASHORN_DEBUG_MODE));
sundar@760 1749 debugOkay = true;
sundar@760 1750 } catch (final SecurityException ignored) {
sundar@760 1751 // if no permission, don't initialize Debug object
sundar@760 1752 debugOkay = false;
sundar@760 1753 }
sundar@760 1754
sundar@760 1755 } else {
sundar@760 1756 debugOkay = true;
sundar@760 1757 }
sundar@760 1758
sundar@760 1759 if (debugOkay) {
sundar@760 1760 initDebug();
sundar@760 1761 }
jlaskey@3 1762 }
jlaskey@3 1763
jlaskey@3 1764 copyBuiltins();
jlaskey@3 1765
jlaskey@3 1766 // expose script (command line) arguments as "arguments" property of global
attila@963 1767 arguments = wrapAsObject(env.getArguments().toArray());
sundar@118 1768 if (env._scripting) {
jlaskey@3 1769 // synonym for "arguments" in scripting mode
attila@963 1770 addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, arguments);
attila@963 1771 }
attila@963 1772
attila@963 1773 if (engine != null) {
attila@963 1774 final int NOT_ENUMERABLE_NOT_CONFIG = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE;
attila@963 1775 scontextProperty = addOwnProperty("context", NOT_ENUMERABLE_NOT_CONFIG, null);
attila@963 1776 addOwnProperty("engine", NOT_ENUMERABLE_NOT_CONFIG, engine);
attila@963 1777 // default file name
attila@963 1778 addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null);
attila@963 1779 // __noSuchProperty__ hook for ScriptContext search of missing variables
attila@963 1780 final ScriptFunction noSuchProp = ScriptFunctionImpl.makeStrictFunction(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY);
attila@963 1781 addOwnProperty(NO_SUCH_PROPERTY_NAME, Attribute.NOT_ENUMERABLE, noSuchProp);
jlaskey@3 1782 }
jlaskey@3 1783 }
jlaskey@3 1784
jlaskey@3 1785 private void initErrorObjects() {
jlaskey@3 1786 // Error objects
attila@963 1787 this.builtinError = initConstructor("Error", ScriptFunction.class);
jlaskey@3 1788 final ScriptObject errorProto = getErrorPrototype();
jlaskey@3 1789
jlaskey@3 1790 // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
jlaskey@3 1791 final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK);
jlaskey@3 1792 final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", NativeError.SET_STACK);
jlaskey@3 1793 errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
jlaskey@3 1794 final ScriptFunction getLineNumber = ScriptFunctionImpl.makeFunction("getLineNumber", NativeError.GET_LINENUMBER);
jlaskey@3 1795 final ScriptFunction setLineNumber = ScriptFunctionImpl.makeFunction("setLineNumber", NativeError.SET_LINENUMBER);
jlaskey@3 1796 errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber);
jlaskey@3 1797 final ScriptFunction getColumnNumber = ScriptFunctionImpl.makeFunction("getColumnNumber", NativeError.GET_COLUMNNUMBER);
jlaskey@3 1798 final ScriptFunction setColumnNumber = ScriptFunctionImpl.makeFunction("setColumnNumber", NativeError.SET_COLUMNNUMBER);
jlaskey@3 1799 errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber);
jlaskey@3 1800 final ScriptFunction getFileName = ScriptFunctionImpl.makeFunction("getFileName", NativeError.GET_FILENAME);
jlaskey@3 1801 final ScriptFunction setFileName = ScriptFunctionImpl.makeFunction("setFileName", NativeError.SET_FILENAME);
jlaskey@3 1802 errorProto.addOwnProperty("fileName", Attribute.NOT_ENUMERABLE, getFileName, setFileName);
jlaskey@3 1803
jlaskey@3 1804 // ECMA 15.11.4.2 Error.prototype.name
jlaskey@3 1805 // Error.prototype.name = "Error";
sundar@344 1806 errorProto.set(NativeError.NAME, "Error", false);
jlaskey@3 1807 // ECMA 15.11.4.3 Error.prototype.message
jlaskey@3 1808 // Error.prototype.message = "";
sundar@344 1809 errorProto.set(NativeError.MESSAGE, "", false);
jlaskey@3 1810
jlaskey@3 1811 this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
jlaskey@3 1812 this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
jlaskey@3 1813 this.builtinReferenceError = initErrorSubtype("ReferenceError", errorProto);
jlaskey@3 1814 this.builtinSyntaxError = initErrorSubtype("SyntaxError", errorProto);
jlaskey@3 1815 this.builtinTypeError = initErrorSubtype("TypeError", errorProto);
jlaskey@3 1816 this.builtinURIError = initErrorSubtype("URIError", errorProto);
jlaskey@3 1817 }
jlaskey@3 1818
jlaskey@3 1819 private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
attila@963 1820 final ScriptFunction cons = initConstructor(name, ScriptFunction.class);
jlaskey@3 1821 final ScriptObject prototype = ScriptFunction.getPrototype(cons);
sundar@344 1822 prototype.set(NativeError.NAME, name, false);
sundar@344 1823 prototype.set(NativeError.MESSAGE, "", false);
hannesw@766 1824 prototype.setInitialProto(errorProto);
attila@963 1825 return cons;
jlaskey@3 1826 }
jlaskey@3 1827
jlaskey@3 1828 private void initJavaAccess() {
jlaskey@3 1829 final ScriptObject objectProto = getObjectPrototype();
jlaskey@3 1830 this.builtinPackages = new NativeJavaPackage("", objectProto);
sundar@146 1831 this.builtinCom = new NativeJavaPackage("com", objectProto);
sundar@146 1832 this.builtinEdu = new NativeJavaPackage("edu", objectProto);
jlaskey@3 1833 this.builtinJava = new NativeJavaPackage("java", objectProto);
sundar@146 1834 this.builtinJavafx = new NativeJavaPackage("javafx", objectProto);
jlaskey@3 1835 this.builtinJavax = new NativeJavaPackage("javax", objectProto);
sundar@146 1836 this.builtinOrg = new NativeJavaPackage("org", objectProto);
attila@963 1837 this.builtinJavaImporter = initConstructor("JavaImporter", ScriptFunction.class);
attila@963 1838 this.builtinJavaApi = initConstructor("Java", ScriptObject.class);
jlaskey@3 1839 }
jlaskey@3 1840
sundar@418 1841 private void initScripting(final ScriptEnvironment scriptEnv) {
jlaskey@3 1842 Object value;
jlaskey@3 1843 value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE);
jlaskey@3 1844 addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);
jlaskey@3 1845
sundar@52 1846 value = ScriptFunctionImpl.makeFunction("readFully", ScriptingFunctions.READFULLY);
sundar@52 1847 addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value);
jlaskey@3 1848
jlaskey@67 1849 final String execName = ScriptingFunctions.EXEC_NAME;
jlaskey@67 1850 value = ScriptFunctionImpl.makeFunction(execName, ScriptingFunctions.EXEC);
jlaskey@67 1851 addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value);
jlaskey@67 1852
jlaskey@3 1853 // Nashorn extension: global.echo (scripting-mode-only)
jlaskey@3 1854 // alias for "print"
jlaskey@3 1855 value = get("print");
jlaskey@3 1856 addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value);
jlaskey@3 1857
jlaskey@3 1858 // Nashorn extension: global.$OPTIONS (scripting-mode-only)
hannesw@380 1859 final ScriptObject options = newObject();
sundar@136 1860 copyOptions(options, scriptEnv);
sundar@136 1861 addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options);
jlaskey@67 1862
jlaskey@67 1863 // Nashorn extension: global.$ENV (scripting-mode-only)
sundar@69 1864 if (System.getSecurityManager() == null) {
sundar@69 1865 // do not fill $ENV if we have a security manager around
sundar@69 1866 // Retrieve current state of ENV variables.
hannesw@380 1867 final ScriptObject env = newObject();
sundar@541 1868 env.putAll(System.getenv(), scriptEnv._strict);
sundar@69 1869 addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env);
sundar@69 1870 } else {
sundar@69 1871 addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
sundar@69 1872 }
sundar@69 1873
sundar@69 1874 // add other special properties for exec support
sundar@69 1875 addOwnProperty(ScriptingFunctions.OUT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
sundar@69 1876 addOwnProperty(ScriptingFunctions.ERR_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
sundar@69 1877 addOwnProperty(ScriptingFunctions.EXIT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
jlaskey@3 1878 }
jlaskey@3 1879
lagergren@139 1880 private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
attila@962 1881 for (final Field f : scriptEnv.getClass().getFields()) {
sundar@492 1882 try {
sundar@492 1883 options.set(f.getName(), f.get(scriptEnv), false);
sundar@492 1884 } catch (final IllegalArgumentException | IllegalAccessException exp) {
sundar@492 1885 throw new RuntimeException(exp);
sundar@136 1886 }
sundar@492 1887 }
sundar@136 1888 }
sundar@136 1889
jlaskey@3 1890 private void initTypedArray() {
attila@963 1891 this.builtinArrayBuffer = initConstructor("ArrayBuffer", ScriptFunction.class);
attila@963 1892 this.builtinDataView = initConstructor("DataView", ScriptFunction.class);
attila@963 1893 this.builtinInt8Array = initConstructor("Int8Array", ScriptFunction.class);
attila@963 1894 this.builtinUint8Array = initConstructor("Uint8Array", ScriptFunction.class);
attila@963 1895 this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray", ScriptFunction.class);
attila@963 1896 this.builtinInt16Array = initConstructor("Int16Array", ScriptFunction.class);
attila@963 1897 this.builtinUint16Array = initConstructor("Uint16Array", ScriptFunction.class);
attila@963 1898 this.builtinInt32Array = initConstructor("Int32Array", ScriptFunction.class);
attila@963 1899 this.builtinUint32Array = initConstructor("Uint32Array", ScriptFunction.class);
attila@963 1900 this.builtinFloat32Array = initConstructor("Float32Array", ScriptFunction.class);
attila@963 1901 this.builtinFloat64Array = initConstructor("Float64Array", ScriptFunction.class);
jlaskey@3 1902 }
jlaskey@3 1903
jlaskey@3 1904 private void copyBuiltins() {
jlaskey@3 1905 this.array = this.builtinArray;
jlaskey@3 1906 this._boolean = this.builtinBoolean;
jlaskey@3 1907 this.date = this.builtinDate;
jlaskey@3 1908 this.error = this.builtinError;
jlaskey@3 1909 this.evalError = this.builtinEvalError;
jlaskey@3 1910 this.function = this.builtinFunction;
jlaskey@3 1911 this.jsadapter = this.builtinJSAdapter;
jlaskey@3 1912 this.json = this.builtinJSON;
sundar@146 1913 this.com = this.builtinCom;
sundar@146 1914 this.edu = this.builtinEdu;
jlaskey@3 1915 this.java = this.builtinJava;
sundar@146 1916 this.javafx = this.builtinJavafx;
jlaskey@3 1917 this.javax = this.builtinJavax;
sundar@146 1918 this.org = this.builtinOrg;
jlaskey@3 1919 this.javaImporter = this.builtinJavaImporter;
jlaskey@3 1920 this.javaApi = this.builtinJavaApi;
jlaskey@3 1921 this.math = this.builtinMath;
jlaskey@3 1922 this.number = this.builtinNumber;
jlaskey@3 1923 this.object = this.builtinObject;
jlaskey@3 1924 this.packages = this.builtinPackages;
jlaskey@3 1925 this.rangeError = this.builtinRangeError;
jlaskey@3 1926 this.referenceError = this.builtinReferenceError;
jlaskey@3 1927 this.regexp = this.builtinRegExp;
jlaskey@3 1928 this.string = this.builtinString;
jlaskey@3 1929 this.syntaxError = this.builtinSyntaxError;
jlaskey@3 1930 this.typeError = this.builtinTypeError;
jlaskey@3 1931 this.uriError = this.builtinURIError;
jlaskey@3 1932 this.arrayBuffer = this.builtinArrayBuffer;
sundar@770 1933 this.dataView = this.builtinDataView;
jlaskey@3 1934 this.int8Array = this.builtinInt8Array;
jlaskey@3 1935 this.uint8Array = this.builtinUint8Array;
jlaskey@3 1936 this.uint8ClampedArray = this.builtinUint8ClampedArray;
jlaskey@3 1937 this.int16Array = this.builtinInt16Array;
jlaskey@3 1938 this.uint16Array = this.builtinUint16Array;
jlaskey@3 1939 this.int32Array = this.builtinInt32Array;
jlaskey@3 1940 this.uint32Array = this.builtinUint32Array;
jlaskey@3 1941 this.float32Array = this.builtinFloat32Array;
jlaskey@3 1942 this.float64Array = this.builtinFloat64Array;
jlaskey@3 1943 }
jlaskey@3 1944
jlaskey@3 1945 private void initDebug() {
attila@963 1946 this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug", ScriptObject.class));
jlaskey@3 1947 }
jlaskey@3 1948
attila@963 1949 private Object printImpl(final boolean newLine, final Object... objects) {
attila@963 1950 @SuppressWarnings("resource")
attila@963 1951 final PrintWriter out = scontext != null? new PrintWriter(scontext.getWriter()) : getContext().getEnv().getOut();
jlaskey@315 1952 final StringBuilder sb = new StringBuilder();
jlaskey@3 1953
attila@963 1954 for (final Object obj : objects) {
jlaskey@315 1955 if (sb.length() != 0) {
jlaskey@315 1956 sb.append(' ');
jlaskey@3 1957 }
jlaskey@3 1958
attila@963 1959 sb.append(JSType.toString(obj));
jlaskey@3 1960 }
jlaskey@3 1961
jlaskey@315 1962 // Print all at once to ensure thread friendly result.
jlaskey@3 1963 if (newLine) {
jlaskey@315 1964 out.println(sb.toString());
jlaskey@315 1965 } else {
jlaskey@315 1966 out.print(sb.toString());
jlaskey@3 1967 }
jlaskey@3 1968
jlaskey@3 1969 out.flush();
jlaskey@3 1970
jlaskey@3 1971 return UNDEFINED;
jlaskey@3 1972 }
jlaskey@3 1973
jlaskey@3 1974 /**
jlaskey@3 1975 * These classes are generated by nasgen tool and so we have to use
jlaskey@3 1976 * reflection to load and create new instance of these classes.
jlaskey@3 1977 */
attila@963 1978 private <T extends ScriptObject> T initConstructor(final String name, final Class<T> clazz) {
jlaskey@3 1979 try {
jlaskey@3 1980 // Assuming class name pattern for built-in JS constructors.
jlaskey@3 1981 final StringBuilder sb = new StringBuilder("jdk.nashorn.internal.objects.");
jlaskey@3 1982
jlaskey@3 1983 sb.append("Native");
jlaskey@3 1984 sb.append(name);
jlaskey@3 1985 sb.append("$Constructor");
jlaskey@3 1986
attila@963 1987 final Class<?> funcClass = Class.forName(sb.toString());
attila@963 1988 final T res = clazz.cast(funcClass.newInstance());
jlaskey@3 1989
jlaskey@3 1990 if (res instanceof ScriptFunction) {
jlaskey@3 1991 // All global constructor prototypes are not-writable,
jlaskey@3 1992 // not-enumerable and not-configurable.
jlaskey@3 1993 final ScriptFunction func = (ScriptFunction)res;
jlaskey@3 1994 func.modifyOwnProperty(func.getProperty("prototype"), Attribute.NON_ENUMERABLE_CONSTANT);
jlaskey@3 1995 }
jlaskey@3 1996
jlaskey@3 1997 if (res.getProto() == null) {
hannesw@766 1998 res.setInitialProto(getObjectPrototype());
jlaskey@3 1999 }
jlaskey@3 2000
attila@963 2001 res.setIsBuiltin();
jlaskey@3 2002 return res;
jlaskey@3 2003 } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
jlaskey@3 2004 throw new RuntimeException(e);
jlaskey@3 2005 }
jlaskey@3 2006 }
jlaskey@3 2007
jlaskey@3 2008 // Function and Object constructors are inter-dependent. Also,
jlaskey@3 2009 // Function.prototype
jlaskey@3 2010 // functions are not properly initialized. We fix the references here.
jlaskey@3 2011 // NOTE: be careful if you want to re-order the operations here. You may
jlaskey@3 2012 // have
jlaskey@3 2013 // to play with object references carefully!!
jlaskey@3 2014 private void initFunctionAndObject() {
jlaskey@3 2015 // First-n-foremost is Function
attila@963 2016 this.builtinFunction = initConstructor("Function", ScriptFunction.class);
jlaskey@3 2017
jlaskey@3 2018 // create global anonymous function
attila@963 2019 final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction();
jlaskey@3 2020 // need to copy over members of Function.prototype to anon function
jlaskey@3 2021 anon.addBoundProperties(getFunctionPrototype());
jlaskey@3 2022
jlaskey@3 2023 // Function.prototype === Object.getPrototypeOf(Function) ===
jlaskey@3 2024 // <anon-function>
hannesw@766 2025 builtinFunction.setInitialProto(anon);
jlaskey@3 2026 builtinFunction.setPrototype(anon);
sundar@344 2027 anon.set("constructor", builtinFunction, false);
jlaskey@3 2028 anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
jlaskey@3 2029
sundar@690 2030 // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
hannesw@769 2031 this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, 0);
sundar@690 2032 typeErrorThrower.setPrototype(UNDEFINED);
sundar@690 2033 // Non-constructor built-in functions do not have "prototype" property
sundar@690 2034 typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
sundar@690 2035 typeErrorThrower.preventExtensions();
sundar@690 2036
jlaskey@3 2037 // now initialize Object
attila@963 2038 this.builtinObject = initConstructor("Object", ScriptFunction.class);
jlaskey@3 2039 final ScriptObject ObjectPrototype = getObjectPrototype();
jlaskey@3 2040 // Object.getPrototypeOf(Function.prototype) === Object.prototype
hannesw@766 2041 anon.setInitialProto(ObjectPrototype);
jlaskey@3 2042
sundar@847 2043 // ES6 draft compliant __proto__ property of Object.prototype
sundar@847 2044 // accessors on Object.prototype for "__proto__"
sundar@866 2045 final ScriptFunction getProto = ScriptFunctionImpl.makeFunction("getProto", NativeObject.GET__PROTO__);
sundar@866 2046 final ScriptFunction setProto = ScriptFunctionImpl.makeFunction("setProto", NativeObject.SET__PROTO__);
sundar@847 2047 ObjectPrototype.addOwnProperty("__proto__", Attribute.NOT_ENUMERABLE, getProto, setProto);
sundar@847 2048
jlaskey@3 2049 // Function valued properties of Function.prototype were not properly
jlaskey@3 2050 // initialized. Because, these were created before global.function and
jlaskey@3 2051 // global.object were not initialized.
jlaskey@3 2052 jdk.nashorn.internal.runtime.Property[] properties = getFunctionPrototype().getMap().getProperties();
jlaskey@3 2053 for (final jdk.nashorn.internal.runtime.Property property : properties) {
jlaskey@3 2054 final Object key = property.getKey();
jlaskey@3 2055 final Object value = builtinFunction.get(key);
jlaskey@3 2056
jlaskey@3 2057 if (value instanceof ScriptFunction && value != anon) {
jlaskey@3 2058 final ScriptFunction func = (ScriptFunction)value;
hannesw@766 2059 func.setInitialProto(getFunctionPrototype());
jlaskey@3 2060 final ScriptObject prototype = ScriptFunction.getPrototype(func);
jlaskey@3 2061 if (prototype != null) {
hannesw@766 2062 prototype.setInitialProto(ObjectPrototype);
jlaskey@3 2063 }
jlaskey@3 2064 }
jlaskey@3 2065 }
jlaskey@3 2066
jlaskey@3 2067 // For function valued properties of Object and Object.prototype, make
jlaskey@3 2068 // sure prototype's proto chain ends with Object.prototype
jlaskey@3 2069 for (final jdk.nashorn.internal.runtime.Property property : builtinObject.getMap().getProperties()) {
jlaskey@3 2070 final Object key = property.getKey();
jlaskey@3 2071 final Object value = builtinObject.get(key);
jlaskey@3 2072
jlaskey@3 2073 if (value instanceof ScriptFunction) {
jlaskey@3 2074 final ScriptFunction func = (ScriptFunction)value;
jlaskey@3 2075 final ScriptObject prototype = ScriptFunction.getPrototype(func);
jlaskey@3 2076 if (prototype != null) {
hannesw@766 2077 prototype.setInitialProto(ObjectPrototype);
jlaskey@3 2078 }
jlaskey@3 2079 }
jlaskey@3 2080 }
jlaskey@3 2081
attila@963 2082 //make sure apply and call have the same invalidation switchpoint
attila@963 2083 final SwitchPoint sp = new SwitchPoint();
attila@963 2084 optimisticFunctionMap.put("apply", sp);
attila@963 2085 optimisticFunctionMap.put("call", sp);
attila@963 2086 getFunctionPrototype().getProperty("apply").setChangeCallback(sp);
attila@963 2087 getFunctionPrototype().getProperty("call").setChangeCallback(sp);
attila@963 2088
jlaskey@3 2089 properties = getObjectPrototype().getMap().getProperties();
attila@963 2090
jlaskey@3 2091 for (final jdk.nashorn.internal.runtime.Property property : properties) {
jlaskey@3 2092 final Object key = property.getKey();
jlaskey@3 2093 if (key.equals("constructor")) {
jlaskey@3 2094 continue;
jlaskey@3 2095 }
jlaskey@3 2096
attila@963 2097 final Object value = ObjectPrototype.get(key);
jlaskey@3 2098 if (value instanceof ScriptFunction) {
jlaskey@3 2099 final ScriptFunction func = (ScriptFunction)value;
jlaskey@3 2100 final ScriptObject prototype = ScriptFunction.getPrototype(func);
jlaskey@3 2101 if (prototype != null) {
hannesw@766 2102 prototype.setInitialProto(ObjectPrototype);
jlaskey@3 2103 }
jlaskey@3 2104 }
jlaskey@3 2105 }
jlaskey@3 2106 }
jlaskey@3 2107
attila@963 2108 private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
attila@963 2109 return MH.findVirtual(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
attila@963 2110 }
attila@963 2111
attila@963 2112 private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
sundar@414 2113 return MH.findStatic(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
jlaskey@3 2114 }
hannesw@79 2115
hannesw@114 2116 RegExpResult getLastRegExpResult() {
hannesw@114 2117 return lastRegExpResult;
hannesw@79 2118 }
hannesw@79 2119
hannesw@114 2120 void setLastRegExpResult(final RegExpResult regExpResult) {
hannesw@114 2121 this.lastRegExpResult = regExpResult;
hannesw@79 2122 }
hannesw@79 2123
attila@963 2124 @Override
attila@963 2125 protected boolean isGlobal() {
attila@963 2126 return true;
attila@963 2127 }
attila@963 2128
attila@963 2129 /**
attila@963 2130 * Check if there is a switchpoint for a reserved name. If there
attila@963 2131 * is, it must be invalidated upon properties with this name
attila@963 2132 * @param name property name
attila@963 2133 * @return switchpoint for invalidating this property, or null if not registered
attila@963 2134 */
attila@963 2135 public SwitchPoint getChangeCallback(final String name) {
attila@963 2136 return optimisticFunctionMap.get(name);
attila@963 2137 }
attila@963 2138
attila@963 2139 /**
attila@963 2140 * Is this a special name, that might be subject to invalidation
attila@963 2141 * on write, such as "apply" or "call"
attila@963 2142 * @param name name to check
attila@963 2143 * @return true if special name
attila@963 2144 */
attila@963 2145 public boolean isSpecialName(final String name) {
attila@963 2146 return getChangeCallback(name) != null;
attila@963 2147 }
attila@963 2148
attila@963 2149 /**
attila@963 2150 * Check if a reserved property name is invalidated
attila@963 2151 * @param name property name
attila@963 2152 * @return true if someone has written to it since Global was instantiated
attila@963 2153 */
attila@963 2154 public boolean isSpecialNameValid(final String name) {
attila@963 2155 final SwitchPoint sp = getChangeCallback(name);
attila@963 2156 return sp != null && !sp.hasBeenInvalidated();
attila@963 2157 }
attila@963 2158
attila@963 2159 /**
attila@963 2160 * Tag a reserved name as invalidated - used when someone writes
attila@963 2161 * to a property with this name - overly conservative, but link time
attila@963 2162 * is too late to apply e.g. apply-&gt;call specialization
attila@963 2163 * @param name property name
attila@963 2164 */
attila@963 2165 public void invalidateReservedName(final String name) {
attila@963 2166 final SwitchPoint sp = getChangeCallback(name);
attila@963 2167 if (sp != null) {
attila@963 2168 getContext().getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint");
attila@963 2169 SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
attila@963 2170 }
attila@963 2171 }
attila@963 2172
attila@963 2173 /**
attila@963 2174 * Bootstrapper for invalidating a builtin name
attila@963 2175 * @param lookup lookup
attila@963 2176 * @param name name to invalidate
attila@963 2177 * @param type methodhandle type
attila@963 2178 * @return callsite for invalidator
attila@963 2179 */
attila@963 2180 public static CallSite invalidateNameBootstrap(final MethodHandles.Lookup lookup, final String name, final MethodType type) {
attila@963 2181 final MethodHandle target = MH.insertArguments(Global.instance().INVALIDATE_RESERVED_NAME, 0, name);
attila@963 2182 return new ConstantCallSite(target);
attila@963 2183 }
attila@963 2184
attila@963 2185
jlaskey@3 2186 }

mercurial