src/jdk/nashorn/internal/runtime/ScriptRuntime.java

Print this page




 335             return ((Iterable<?>)obj).iterator();
 336         }
 337 
 338         return Collections.emptyIterator();
 339     }
 340 
 341     /**
 342      * Merge a scope into its prototype's map.
 343      * Merge a scope into its prototype.
 344      *
 345      * @param scope Scope to merge.
 346      * @return prototype object after merge
 347      */
 348     public static ScriptObject mergeScope(final ScriptObject scope) {
 349         final ScriptObject global = scope.getProto();
 350         global.addBoundProperties(scope);
 351         return global;
 352     }
 353 
 354     /**
 355      * Check that the target function is associated with current Context. And also make sure that 'self', if
 356      * ScriptObject, is from current context.
 357      *
 358      * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve
 359      * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker}
 360      * for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead.
 361      *
 362      * @param target ScriptFunction object.
 363      * @param self   Receiver in call.
 364      * @param args   Call arguments.
 365      * @return Call result.
 366      */
 367     public static Object checkAndApply(final ScriptFunction target, final Object self, final Object... args) {
 368         final ScriptObject global = Context.getGlobalTrusted();
 369         assert (global instanceof GlobalObject): "No current global set";
 370 
 371         if (target.getContext() != global.getContext()) {
 372             throw new IllegalArgumentException("'target' function is not from current Context");
 373         }
 374 
 375         if (self instanceof ScriptObject && ((ScriptObject)self).getContext() != global.getContext()) {
 376             throw new IllegalArgumentException("'self' object is not from current Context");
 377         }
 378 
 379         // all in order - call real 'apply'
 380         return apply(target, self, args);
 381     }
 382 
 383     /**
 384      * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve
 385      * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker}
 386      * for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead.
 387      *
 388      * @param target ScriptFunction object.
 389      * @param self   Receiver in call.
 390      * @param args   Call arguments.
 391      * @return Call result.
 392      */
 393     public static Object apply(final ScriptFunction target, final Object self, final Object... args) {
 394         try {
 395             return target.invoke(self, args);
 396         } catch (final RuntimeException | Error e) {
 397             throw e;
 398         } catch (final Throwable t) {
 399             throw new RuntimeException(t);
 400         }
 401     }
 402 
 403     /**
 404      * Check that the target function is associated with current Context.
 405      * And also make sure that 'self', if ScriptObject, is from current context.
 406      *
 407      * Call a function as a constructor given args.
 408      *
 409      * @param target ScriptFunction object.
 410      * @param args   Call arguments.
 411      * @return Constructor call result.
 412      */
 413     public static Object checkAndConstruct(final ScriptFunction target, final Object... args) {
 414         final ScriptObject global = Context.getGlobalTrusted();
 415         assert (global instanceof GlobalObject): "No current global set";
 416 
 417         if (target.getContext() != global.getContext()) {
 418             throw new IllegalArgumentException("'target' function is not from current Context");
 419         }
 420 
 421         // all in order - call real 'construct'
 422         return construct(target, args);
 423     }
 424 
 425     /**
 426      * Call a script function as a constructor with given args.
 427      *
 428      * @param target ScriptFunction object.
 429      * @param args   Call arguments.
 430      * @return Constructor call result.
 431      */
 432     public static Object construct(final ScriptFunction target, final Object... args) {
 433         try {
 434             return target.construct(args);
 435         } catch (final RuntimeException | Error e) {
 436             throw e;
 437         } catch (final Throwable t) {
 438             throw new RuntimeException(t);
 439         }
 440     }
 441 
 442     /**
 443      * Generic implementation of ECMA 9.12 - SameValue algorithm
 444      *
 445      * @param x first value to compare


 503     public static boolean isJSWhitespace(final char ch) {
 504         return Lexer.isJSWhitespace(ch);
 505     }
 506 
 507     /**
 508      * Entering a {@code with} node requires new scope. This is the implementation
 509      *
 510      * @param scope      existing scope
 511      * @param expression expression in with
 512      *
 513      * @return {@link WithObject} that is the new scope
 514      */
 515     public static ScriptObject openWith(final ScriptObject scope, final Object expression) {
 516         final ScriptObject global = Context.getGlobalTrusted();
 517         if (expression == UNDEFINED) {
 518             throw typeError(global, "cant.apply.with.to.undefined");
 519         } else if (expression == null) {
 520             throw typeError(global, "cant.apply.with.to.null");
 521         }
 522 
 523         final ScriptObject withObject = new WithObject(scope, JSType.toScriptObject(global, expression));



 524 
 525         return withObject;
 526     }
 527 
 528     /**
 529      * Exiting a {@code with} node requires restoring scope. This is the implementation
 530      *
 531      * @param scope existing scope
 532      *
 533      * @return restored scope
 534      */
 535     public static ScriptObject closeWith(final ScriptObject scope) {
 536         if (scope instanceof WithObject) {
 537             return scope.getProto();
 538         }
 539         return scope;
 540     }
 541 
 542     /**
 543      * ECMA 11.6.1 - The addition operator (+) - generic implementation
 544      * Compiler specializes using {@link jdk.nashorn.internal.codegen.RuntimeCallSite}
 545      * if any type information is available for any of the operands
 546      *
 547      * @param x  first term
 548      * @param y  second term
 549      *
 550      * @return result of addition
 551      */
 552     public static Object ADD(final Object x, final Object y) {
 553         // This prefix code to handle Number special is for optimization.
 554         final boolean xIsNumber = x instanceof Number;
 555         final boolean yIsNumber = y instanceof Number;
 556 
 557         if (xIsNumber && yIsNumber) {




 335             return ((Iterable<?>)obj).iterator();
 336         }
 337 
 338         return Collections.emptyIterator();
 339     }
 340 
 341     /**
 342      * Merge a scope into its prototype's map.
 343      * Merge a scope into its prototype.
 344      *
 345      * @param scope Scope to merge.
 346      * @return prototype object after merge
 347      */
 348     public static ScriptObject mergeScope(final ScriptObject scope) {
 349         final ScriptObject global = scope.getProto();
 350         global.addBoundProperties(scope);
 351         return global;
 352     }
 353 
 354     /**





























 355      * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve
 356      * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker}
 357      * for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead.
 358      *
 359      * @param target ScriptFunction object.
 360      * @param self   Receiver in call.
 361      * @param args   Call arguments.
 362      * @return Call result.
 363      */
 364     public static Object apply(final ScriptFunction target, final Object self, final Object... args) {
 365         try {
 366             return target.invoke(self, args);
 367         } catch (final RuntimeException | Error e) {
 368             throw e;
 369         } catch (final Throwable t) {
 370             throw new RuntimeException(t);
 371         }
 372     }
 373 
 374     /**






















 375      * Call a script function as a constructor with given args.
 376      *
 377      * @param target ScriptFunction object.
 378      * @param args   Call arguments.
 379      * @return Constructor call result.
 380      */
 381     public static Object construct(final ScriptFunction target, final Object... args) {
 382         try {
 383             return target.construct(args);
 384         } catch (final RuntimeException | Error e) {
 385             throw e;
 386         } catch (final Throwable t) {
 387             throw new RuntimeException(t);
 388         }
 389     }
 390 
 391     /**
 392      * Generic implementation of ECMA 9.12 - SameValue algorithm
 393      *
 394      * @param x first value to compare


 452     public static boolean isJSWhitespace(final char ch) {
 453         return Lexer.isJSWhitespace(ch);
 454     }
 455 
 456     /**
 457      * Entering a {@code with} node requires new scope. This is the implementation
 458      *
 459      * @param scope      existing scope
 460      * @param expression expression in with
 461      *
 462      * @return {@link WithObject} that is the new scope
 463      */
 464     public static ScriptObject openWith(final ScriptObject scope, final Object expression) {
 465         final ScriptObject global = Context.getGlobalTrusted();
 466         if (expression == UNDEFINED) {
 467             throw typeError(global, "cant.apply.with.to.undefined");
 468         } else if (expression == null) {
 469             throw typeError(global, "cant.apply.with.to.null");
 470         }
 471 
 472         final Object wrappedExpr = JSType.toScriptObject(global, expression);
 473         if (wrappedExpr instanceof ScriptObject) {
 474             return new WithObject(scope, (ScriptObject)wrappedExpr);
 475         }
 476 
 477         throw typeError(global, "cant.apply.with.to.non.scriptobject");
 478     }
 479 
 480     /**
 481      * Exiting a {@code with} node requires restoring scope. This is the implementation
 482      *
 483      * @param scope existing scope
 484      *
 485      * @return restored scope
 486      */
 487     public static ScriptObject closeWith(final ScriptObject scope) {
 488         if (scope instanceof WithObject) {
 489             return ((WithObject)scope).getParentScope();
 490         }
 491         return scope;
 492     }
 493 
 494     /**
 495      * ECMA 11.6.1 - The addition operator (+) - generic implementation
 496      * Compiler specializes using {@link jdk.nashorn.internal.codegen.RuntimeCallSite}
 497      * if any type information is available for any of the operands
 498      *
 499      * @param x  first term
 500      * @param y  second term
 501      *
 502      * @return result of addition
 503      */
 504     public static Object ADD(final Object x, final Object y) {
 505         // This prefix code to handle Number special is for optimization.
 506         final boolean xIsNumber = x instanceof Number;
 507         final boolean yIsNumber = y instanceof Number;
 508 
 509         if (xIsNumber && yIsNumber) {