741f662a60
Number of checked arguments is corrected in ICData objects created when reading bytecode, both for instance and static calls. InstanceCall1 and InstanceCall2 bytecode instructions are replaced with InstanceCall which works for any number of checked arguments. This makes decision on number of checked arguments internal to VM and it is no longer exposed to bytecode. Change-Id: I0bba01eca6347336f3832de863b2ce4715fda04a Reviewed-on: https://dart-review.googlesource.com/69421 Reviewed-by: Régis Crelier <regis@google.com> Reviewed-by: Zach Anderson <zra@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
587 lines
16 KiB
Plaintext
587 lines
16 KiB
Plaintext
library #lib;
|
|
import self as self;
|
|
import "dart:core" as core;
|
|
import "dart:_internal" as _in;
|
|
|
|
typedef _ScheduleImmediateClosure = (() → void) → void;
|
|
class _ScheduleImmediate extends core::Object {
|
|
static field (() → void) → void _closure = null;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
Push FP[-5]
|
|
PushConstant CP#1
|
|
IndirectStaticCall 1, CP#0
|
|
Drop1
|
|
PushConstant CP#2
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
|
|
[2] = Null
|
|
}
|
|
] synthetic constructor •() → void
|
|
: super core::Object::•()
|
|
;
|
|
}
|
|
class _NamespaceImpl extends core::Object implements self::_Namespace {
|
|
static field self::_NamespaceImpl _cachedNamespace = null;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
Push FP[-5]
|
|
PushConstant CP#1
|
|
IndirectStaticCall 1, CP#0
|
|
Drop1
|
|
PushConstant CP#2
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
|
|
[2] = Null
|
|
}
|
|
] constructor _() → void
|
|
: super core::Object::•()
|
|
;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
Push FP[-6]
|
|
Push FP[-5]
|
|
NativeCall CP#0
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = NativeEntry Namespace_Create
|
|
}
|
|
] @_in::ExternalName::•("Namespace_Create")
|
|
external static method _create(self::_NamespaceImpl namespace, dynamic n) → self::_NamespaceImpl;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
Push FP[-5]
|
|
NativeCall CP#0
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = NativeEntry Namespace_GetPointer
|
|
}
|
|
] @_in::ExternalName::•("Namespace_GetPointer")
|
|
external static method _getPointer(self::_NamespaceImpl namespace) → core::int;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
NativeCall CP#0
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = NativeEntry Namespace_GetDefault
|
|
}
|
|
] @_in::ExternalName::•("Namespace_GetDefault")
|
|
external static method _getDefault() → core::int;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 2
|
|
CheckStack
|
|
Allocate CP#0
|
|
StoreLocal r1
|
|
Push r1
|
|
PushConstant CP#2
|
|
IndirectStaticCall 1, CP#1
|
|
Drop1
|
|
Push FP[-5]
|
|
PushConstant CP#4
|
|
IndirectStaticCall 2, CP#3
|
|
StoreStaticTOS CP#5
|
|
PushConstant CP#6
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = Class #lib::_NamespaceImpl
|
|
[1] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[2] = StaticICData target '#lib::_NamespaceImpl::_', arg-desc CP#1
|
|
[3] = ArgDesc num-args 2, num-type-args 0, names []
|
|
[4] = StaticICData target '#lib::_NamespaceImpl::_create', arg-desc CP#3
|
|
[5] = StaticField #lib::_NamespaceImpl::_cachedNamespace
|
|
[6] = Null
|
|
}
|
|
] static method _setupNamespace(dynamic namespace) → void {
|
|
self::_NamespaceImpl::_cachedNamespace = self::_NamespaceImpl::_create(new self::_NamespaceImpl::_(), namespace);
|
|
}
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 2
|
|
CheckStack
|
|
PushConstant CP#0
|
|
PushStatic CP#0
|
|
PushConstant CP#1
|
|
InstanceCall 2, CP#3
|
|
AssertBoolean 0
|
|
PushConstant CP#4
|
|
IfNeStrictTOS
|
|
Jump L1
|
|
Allocate CP#5
|
|
StoreLocal r1
|
|
Push r1
|
|
PushConstant CP#7
|
|
IndirectStaticCall 1, CP#6
|
|
Drop1
|
|
PushConstant CP#9
|
|
IndirectStaticCall 0, CP#8
|
|
PushConstant CP#10
|
|
IndirectStaticCall 2, CP#2
|
|
StoreStaticTOS CP#0
|
|
L1:
|
|
PushConstant CP#0
|
|
PushStatic CP#0
|
|
ReturnTOS
|
|
PushConstant CP#1
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = StaticField #lib::_NamespaceImpl::_cachedNamespace
|
|
[1] = Null
|
|
[2] = ArgDesc num-args 2, num-type-args 0, names []
|
|
[3] = ICData target-name '==', arg-desc CP#2
|
|
[4] = Bool true
|
|
[5] = Class #lib::_NamespaceImpl
|
|
[6] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[7] = StaticICData target '#lib::_NamespaceImpl::_', arg-desc CP#6
|
|
[8] = ArgDesc num-args 0, num-type-args 0, names []
|
|
[9] = StaticICData target '#lib::_NamespaceImpl::_getDefault', arg-desc CP#8
|
|
[10] = StaticICData target '#lib::_NamespaceImpl::_create', arg-desc CP#2
|
|
}
|
|
] static get _namespace() → self::_NamespaceImpl {
|
|
if(self::_NamespaceImpl::_cachedNamespace.{core::Object::==}(null)) {
|
|
self::_NamespaceImpl::_cachedNamespace = self::_NamespaceImpl::_create(new self::_NamespaceImpl::_(), self::_NamespaceImpl::_getDefault());
|
|
}
|
|
return self::_NamespaceImpl::_cachedNamespace;
|
|
}
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
PushConstant CP#1
|
|
IndirectStaticCall 0, CP#0
|
|
PushConstant CP#3
|
|
IndirectStaticCall 1, CP#2
|
|
ReturnTOS
|
|
PushConstant CP#4
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = ArgDesc num-args 0, num-type-args 0, names []
|
|
[1] = StaticICData get target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
|
|
[2] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[3] = StaticICData target '#lib::_NamespaceImpl::_getPointer', arg-desc CP#2
|
|
[4] = Null
|
|
}
|
|
] static get _namespacePointer() → core::int
|
|
return self::_NamespaceImpl::_getPointer(self::_NamespaceImpl::_namespace);
|
|
}
|
|
class _Namespace extends core::Object {
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
Push FP[-5]
|
|
PushConstant CP#1
|
|
IndirectStaticCall 1, CP#0
|
|
Drop1
|
|
PushConstant CP#2
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
|
|
[2] = Null
|
|
}
|
|
] synthetic constructor •() → void
|
|
: super core::Object::•()
|
|
;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
Push FP[-5]
|
|
PushConstant CP#1
|
|
IndirectStaticCall 1, CP#0
|
|
Drop1
|
|
PushConstant CP#2
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[1] = StaticICData target '#lib::_NamespaceImpl::_setupNamespace', arg-desc CP#0
|
|
[2] = Null
|
|
}
|
|
] static method _setupNamespace(dynamic namespace) → void {
|
|
self::_NamespaceImpl::_setupNamespace(namespace);
|
|
}
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
PushConstant CP#1
|
|
IndirectStaticCall 0, CP#0
|
|
ReturnTOS
|
|
PushConstant CP#2
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = ArgDesc num-args 0, num-type-args 0, names []
|
|
[1] = StaticICData get target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
|
|
[2] = Null
|
|
}
|
|
] static get _namespace() → self::_Namespace
|
|
return self::_NamespaceImpl::_namespace;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
PushConstant CP#1
|
|
IndirectStaticCall 0, CP#0
|
|
ReturnTOS
|
|
PushConstant CP#2
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = ArgDesc num-args 0, num-type-args 0, names []
|
|
[1] = StaticICData get target '#lib::_NamespaceImpl::_namespacePointer', arg-desc CP#0
|
|
[2] = Null
|
|
}
|
|
] static get _namespacePointer() → core::int
|
|
return self::_NamespaceImpl::_namespacePointer;
|
|
}
|
|
class VMLibraryHooks extends core::Object {
|
|
static field dynamic timerFactory = null;
|
|
static field dynamic eventHandlerSendData = null;
|
|
static field dynamic timerMillisecondClock = null;
|
|
static field dynamic resourceReadAsBytes = null;
|
|
static field dynamic packageRootString = null;
|
|
static field dynamic packageConfigString = null;
|
|
static field dynamic packageRootUriFuture = null;
|
|
static field dynamic packageConfigUriFuture = null;
|
|
static field dynamic resolvePackageUriFuture = null;
|
|
static field dynamic _computeScriptUri = null;
|
|
static field dynamic _cachedScript = null;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
Push FP[-5]
|
|
PushConstant CP#1
|
|
IndirectStaticCall 1, CP#0
|
|
Drop1
|
|
PushConstant CP#2
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
|
|
[2] = Null
|
|
}
|
|
] synthetic constructor •() → void
|
|
: super core::Object::•()
|
|
;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 2
|
|
CheckStack
|
|
Push FP[-5]
|
|
StoreStaticTOS CP#0
|
|
PushConstant CP#1
|
|
StoreStaticTOS CP#2
|
|
PushConstant CP#1
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = StaticField #lib::VMLibraryHooks::_computeScriptUri
|
|
[1] = Null
|
|
[2] = StaticField #lib::VMLibraryHooks::_cachedScript
|
|
}
|
|
] static set platformScript(dynamic f) → void {
|
|
self::VMLibraryHooks::_computeScriptUri = f;
|
|
self::VMLibraryHooks::_cachedScript = null;
|
|
}
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 1
|
|
CheckStack
|
|
PushConstant CP#0
|
|
PushStatic CP#0
|
|
PushConstant CP#1
|
|
InstanceCall 2, CP#3
|
|
AssertBoolean 0
|
|
PushConstant CP#4
|
|
IfNeStrictTOS
|
|
Jump L1
|
|
PushConstant CP#5
|
|
PushStatic CP#5
|
|
PushConstant CP#1
|
|
InstanceCall 2, CP#6
|
|
AssertBoolean 0
|
|
BooleanNegateTOS
|
|
PopLocal r0
|
|
Jump L2
|
|
L1:
|
|
PushConstant CP#7
|
|
PopLocal r0
|
|
L2:
|
|
Push r0
|
|
AssertBoolean 0
|
|
PushConstant CP#4
|
|
IfNeStrictTOS
|
|
Jump L3
|
|
PushConstant CP#5
|
|
PushStatic CP#5
|
|
InstanceCall 1, CP#9
|
|
StoreStaticTOS CP#0
|
|
L3:
|
|
PushConstant CP#0
|
|
PushStatic CP#0
|
|
ReturnTOS
|
|
PushConstant CP#1
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = StaticField #lib::VMLibraryHooks::_cachedScript
|
|
[1] = Null
|
|
[2] = ArgDesc num-args 2, num-type-args 0, names []
|
|
[3] = ICData target-name '==', arg-desc CP#2
|
|
[4] = Bool true
|
|
[5] = StaticField #lib::VMLibraryHooks::_computeScriptUri
|
|
[6] = ICData target-name '==', arg-desc CP#2
|
|
[7] = Bool false
|
|
[8] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[9] = ICData target-name 'call', arg-desc CP#8
|
|
}
|
|
] static get platformScript() → dynamic {
|
|
if(self::VMLibraryHooks::_cachedScript.{core::Object::==}(null) && !self::VMLibraryHooks::_computeScriptUri.{core::Object::==}(null)) {
|
|
self::VMLibraryHooks::_cachedScript = self::VMLibraryHooks::_computeScriptUri.call();
|
|
}
|
|
return self::VMLibraryHooks::_cachedScript;
|
|
}
|
|
}
|
|
static field core::int _stdinFD = 0;
|
|
static field core::int _stdoutFD = 1;
|
|
static field core::int _stderrFD = 2;
|
|
static field core::String _rawScript;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
Push FP[-5]
|
|
NativeCall CP#0
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = NativeEntry Builtin_PrintString
|
|
}
|
|
]@_in::ExternalName::•("Builtin_PrintString")
|
|
external static method _printString(core::String s) → void;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
Push FP[-5]
|
|
InstanceCall 1, CP#1
|
|
PushConstant CP#2
|
|
IndirectStaticCall 1, CP#0
|
|
Drop1
|
|
PushConstant CP#3
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[1] = ICData target-name 'toString', arg-desc CP#0
|
|
[2] = StaticICData target '#lib::_printString', arg-desc CP#0
|
|
[3] = Null
|
|
}
|
|
]static method _print(dynamic arg) → void {
|
|
self::_printString(arg.{core::Object::toString}());
|
|
}
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
PushConstant CP#0
|
|
ReturnTOS
|
|
PushConstant CP#1
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = TearOff #lib::_print
|
|
[1] = Null
|
|
}
|
|
]static method _getPrintClosure() → dynamic
|
|
return self::_print;
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 1
|
|
CheckStack
|
|
Push FP[-5]
|
|
StoreStaticTOS CP#0
|
|
PushConstant CP#1
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = StaticField #lib::_ScheduleImmediate::_closure
|
|
[1] = Null
|
|
}
|
|
]static method _setScheduleImmediateClosure((() → void) → void closure) → void {
|
|
self::_ScheduleImmediate::_closure = closure;
|
|
}
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 3
|
|
CheckStack
|
|
Push FP[-7]
|
|
StoreStaticTOS CP#0
|
|
Push FP[-6]
|
|
StoreStaticTOS CP#1
|
|
Push FP[-5]
|
|
StoreStaticTOS CP#2
|
|
PushConstant CP#3
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = StaticField #lib::_stdinFD
|
|
[1] = StaticField #lib::_stdoutFD
|
|
[2] = StaticField #lib::_stderrFD
|
|
[3] = Null
|
|
}
|
|
]static method _setStdioFDs(core::int stdin, core::int stdout, core::int stderr) → void {
|
|
self::_stdinFD = stdin;
|
|
self::_stdoutFD = stdout;
|
|
self::_stderrFD = stderr;
|
|
}
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 2
|
|
CheckStack
|
|
PushConstant CP#0
|
|
PushStatic CP#0
|
|
PushConstant CP#1
|
|
InstanceCall 2, CP#3
|
|
AssertBoolean 0
|
|
PushConstant CP#4
|
|
IfEqStrictTOS
|
|
Jump L1
|
|
PushConstant CP#0
|
|
PushStatic CP#0
|
|
PushConstant CP#5
|
|
InstanceCall 2, CP#6
|
|
AssertBoolean 0
|
|
PopLocal r1
|
|
Jump L2
|
|
L1:
|
|
PushConstant CP#4
|
|
PopLocal r1
|
|
L2:
|
|
Push r1
|
|
AssertBoolean 0
|
|
PushConstant CP#4
|
|
IfEqStrictTOS
|
|
Jump L3
|
|
PushConstant CP#0
|
|
PushStatic CP#0
|
|
PushConstant CP#7
|
|
InstanceCall 2, CP#8
|
|
AssertBoolean 0
|
|
PopLocal r0
|
|
Jump L4
|
|
L3:
|
|
PushConstant CP#4
|
|
PopLocal r0
|
|
L4:
|
|
Push r0
|
|
AssertBoolean 0
|
|
PushConstant CP#4
|
|
IfNeStrictTOS
|
|
Jump L5
|
|
PushConstant CP#0
|
|
PushStatic CP#0
|
|
PushConstant CP#10
|
|
IndirectStaticCall 1, CP#9
|
|
ReturnTOS
|
|
Jump L6
|
|
L5:
|
|
PushConstant CP#12
|
|
IndirectStaticCall 0, CP#11
|
|
PushConstant CP#13
|
|
PushConstant CP#0
|
|
PushStatic CP#0
|
|
PushConstant CP#14
|
|
IndirectStaticCall 2, CP#2
|
|
InstanceCall 2, CP#15
|
|
ReturnTOS
|
|
L6:
|
|
PushConstant CP#13
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = StaticField #lib::_rawScript
|
|
[1] = String 'http:'
|
|
[2] = ArgDesc num-args 2, num-type-args 0, names []
|
|
[3] = ICData target-name 'startsWith', arg-desc CP#2
|
|
[4] = Bool true
|
|
[5] = String 'https:'
|
|
[6] = ICData target-name 'startsWith', arg-desc CP#2
|
|
[7] = String 'file:'
|
|
[8] = ICData target-name 'startsWith', arg-desc CP#2
|
|
[9] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[10] = StaticICData target 'dart.core::Uri::parse', arg-desc CP#9
|
|
[11] = ArgDesc num-args 0, num-type-args 0, names []
|
|
[12] = StaticICData get target 'dart.core::Uri::base', arg-desc CP#11
|
|
[13] = Null
|
|
[14] = StaticICData target 'dart.core::_Uri::file', arg-desc CP#2
|
|
[15] = ICData target-name 'resolveUri', arg-desc CP#2
|
|
}
|
|
]static method _scriptUri() → core::Uri {
|
|
if(self::_rawScript.{core::String::startsWith}("http:") || self::_rawScript.{core::String::startsWith}("https:") || self::_rawScript.{core::String::startsWith}("file:")) {
|
|
return core::Uri::parse(self::_rawScript);
|
|
}
|
|
else {
|
|
return core::Uri::base.{core::Uri::resolveUri}(core::_Uri::file(self::_rawScript));
|
|
}
|
|
}
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 1
|
|
CheckStack
|
|
PushConstant CP#0
|
|
PushConstant CP#2
|
|
IndirectStaticCall 1, CP#1
|
|
Drop1
|
|
PushConstant CP#3
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = TearOff #lib::_scriptUri
|
|
[1] = ArgDesc num-args 1, num-type-args 0, names []
|
|
[2] = StaticICData set target '#lib::VMLibraryHooks::platformScript', arg-desc CP#1
|
|
[3] = Null
|
|
}
|
|
]static method _setupHooks() → dynamic {
|
|
self::VMLibraryHooks::platformScript = self::_scriptUri;
|
|
}
|
|
[@vm.bytecode=
|
|
Bytecode {
|
|
Entry 0
|
|
CheckStack
|
|
PushConstant CP#0
|
|
ReturnTOS
|
|
}
|
|
ConstantPool {
|
|
[0] = Null
|
|
}
|
|
]static method main() → dynamic {}
|