macros.py 12.3 KB
Newer Older
1
# Copyright 2006-2009 the V8 project authors. All rights reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Dictionary that is passed as defines for js2c.py.
29
# Used for defines that must be defined for all native JS files.
30

31 32 33
const NONE        = 0;
const READ_ONLY   = 1;
const DONT_ENUM   = 2;
34
const DONT_DELETE = 4;
35 36
const NEW_ONE_BYTE_STRING = true;
const NEW_TWO_BYTE_STRING = false;
37 38 39 40 41 42 43 44 45

# Constants used for getter and setter operations.
const GETTER = 0;
const SETTER = 1;

const NO_HINT     = 0;
const NUMBER_HINT = 1;
const STRING_HINT = 2;

46 47 48 49 50 51 52 53
# For date.js.
const HoursPerDay      = 24;
const MinutesPerHour   = 60;
const SecondsPerMinute = 60;
const msPerSecond      = 1000;
const msPerMinute      = 60000;
const msPerHour        = 3600000;
const msPerDay         = 86400000;
54
const msPerMonth       = 2592000000;
55

56 57 58 59 60 61 62
# Note: kDayZeroInJulianDay = ToJulianDay(1970, 0, 1).
const kInvalidDate        = 'Invalid Date';
const kDayZeroInJulianDay = 2440588;
const kMonthMask          = 0x1e0;
const kDayMask            = 0x01f;
const kYearShift          = 9;
const kMonthShift         = 5;
63

64 65 66 67 68 69 70 71
# Limits for parts of the date, so that we support all the dates that
# ECMA 262 - 15.9.1.1 requires us to, but at the same time be sure that
# the date (days since 1970) is in SMI range.
const kMinYear  = -1000000;
const kMaxYear  = 1000000;
const kMinMonth = -10000000;
const kMaxMonth = 10000000;

72 73 74 75 76
# Safe maximum number of arguments to push to stack, when multiplied by
# pointer size. Used by Function.prototype.apply(), Reflect.apply() and
# Reflect.construct().
const kSafeArgumentsLength = 0x800000;

77 78 79 80
# Strict mode flags for passing to %SetProperty
const kSloppyMode = 0;
const kStrictMode = 1;

81 82 83
# Native cache ids.
const STRING_TO_REGEXP_CACHE_ID = 0;

84
# Type query macros.
85 86 87 88
#
# Note: We have special support for typeof(foo) === 'bar' in the compiler.
#       It will *not* generate a runtime typeof call for the most important
#       values of 'bar'.
89 90
macro IS_NULL(arg)              = (arg === null);
macro IS_NULL_OR_UNDEFINED(arg) = (arg == null);
91
macro IS_UNDEFINED(arg)         = (arg === (void 0));
92 93 94
macro IS_NUMBER(arg)            = (typeof(arg) === 'number');
macro IS_STRING(arg)            = (typeof(arg) === 'string');
macro IS_BOOLEAN(arg)           = (typeof(arg) === 'boolean');
95
macro IS_SYMBOL(arg)            = (typeof(arg) === 'symbol');
96
macro IS_OBJECT(arg)            = (%_IsObject(arg));
97
macro IS_ARRAY(arg)             = (%_IsArray(arg));
98
macro IS_FUNCTION(arg)          = (%_IsFunction(arg));
99
macro IS_REGEXP(arg)            = (%_IsRegExp(arg));
100 101 102
macro IS_SET(arg)               = (%_ClassOf(arg) === 'Set');
macro IS_MAP(arg)               = (%_ClassOf(arg) === 'Map');
macro IS_WEAKMAP(arg)           = (%_ClassOf(arg) === 'WeakMap');
103
macro IS_WEAKSET(arg)           = (%_ClassOf(arg) === 'WeakSet');
104 105 106
macro IS_DATE(arg)              = (%_ClassOf(arg) === 'Date');
macro IS_NUMBER_WRAPPER(arg)    = (%_ClassOf(arg) === 'Number');
macro IS_STRING_WRAPPER(arg)    = (%_ClassOf(arg) === 'String');
107
macro IS_SYMBOL_WRAPPER(arg)    = (%_ClassOf(arg) === 'Symbol');
108 109 110 111
macro IS_BOOLEAN_WRAPPER(arg)   = (%_ClassOf(arg) === 'Boolean');
macro IS_ERROR(arg)             = (%_ClassOf(arg) === 'Error');
macro IS_SCRIPT(arg)            = (%_ClassOf(arg) === 'Script');
macro IS_ARGUMENTS(arg)         = (%_ClassOf(arg) === 'Arguments');
112
macro IS_GLOBAL(arg)            = (%_ClassOf(arg) === 'global');
113
macro IS_ARRAYBUFFER(arg)       = (%_ClassOf(arg) === 'ArrayBuffer');
114
macro IS_DATAVIEW(arg)          = (%_ClassOf(arg) === 'DataView');
115
macro IS_GENERATOR(arg)         = (%_ClassOf(arg) === 'Generator');
116 117
macro IS_SET_ITERATOR(arg)      = (%_ClassOf(arg) === 'Set Iterator');
macro IS_MAP_ITERATOR(arg)      = (%_ClassOf(arg) === 'Map Iterator');
118
macro IS_UNDETECTABLE(arg)      = (%_IsUndetectableObject(arg));
119

120 121
# Macro for ECMAScript 5 queries of the type:
# "Type(O) is object."
122 123
# This is the same as being either a function or an object in V8 terminology
# (including proxies).
124
# In addition, an undetectable object is also included by this.
125 126 127 128 129 130 131 132
macro IS_SPEC_OBJECT(arg)   = (%_IsSpecObject(arg));

# Macro for ECMAScript 5 queries of the type:
# "IsCallable(O)"
# We assume here that this is the same as being either a function or a function
# proxy. That ignores host objects with [[Call]] methods, but in most situations
# we cannot handle those anyway.
macro IS_SPEC_FUNCTION(arg) = (%_ClassOf(arg) === 'Function');
133

134 135 136 137
# Macro for ES6 CheckObjectCoercible
# Will throw a TypeError of the form "[functionName] called on null or undefined".
macro CHECK_OBJECT_COERCIBLE(arg, functionName) = if (IS_NULL_OR_UNDEFINED(arg) && !IS_UNDETECTABLE(arg)) throw MakeTypeError('called_on_null_or_undefined', [functionName]);

138 139 140 141 142
# Indices in bound function info retrieved by %BoundFunctionGetBindings(...).
const kBoundFunctionIndex = 0;
const kBoundThisIndex = 1;
const kBoundArgumentsStartIndex = 2;

143 144
# Inline macros. Use %IS_VAR to make sure arg is evaluated only once.
macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
145
macro NUMBER_IS_FINITE(arg) = (%_IsSmi(%IS_VAR(arg)) || ((arg == arg) && (arg != 1/0) && (arg != -1/0)));
146
macro TO_INTEGER(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToInteger(ToNumber(arg)));
147
macro TO_INTEGER_FOR_SIDE_EFFECT(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : ToNumber(arg));
148
macro TO_INTEGER_MAP_MINUS_ZERO(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToIntegerMapMinusZero(ToNumber(arg)));
149 150 151
macro TO_INT32(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : (arg >> 0));
macro TO_UINT32(arg) = (arg >>> 0);
macro TO_STRING_INLINE(arg) = (IS_STRING(%IS_VAR(arg)) ? arg : NonStringToString(arg));
152
macro TO_NUMBER_INLINE(arg) = (IS_NUMBER(%IS_VAR(arg)) ? arg : NonNumberToNumber(arg));
153
macro TO_OBJECT_INLINE(arg) = (IS_SPEC_OBJECT(%IS_VAR(arg)) ? arg : ToObject(arg));
154
macro JSON_NUMBER_TO_STRING(arg) = ((%_IsSmi(%IS_VAR(arg)) || arg - arg == 0) ? %_NumberToString(arg) : "null");
155
macro HAS_OWN_PROPERTY(obj, index) = (%_CallFunction(obj, index, ObjectHasOwnProperty));
156
macro SHOULD_CREATE_WRAPPER(functionName, receiver) = (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(functionName));
157
macro HAS_INDEX(array, index, is_array) = ((is_array && %_HasFastPackedElements(%IS_VAR(array))) ? (index < array.length) : (index in array));
158

159
# Private names.
160 161
# GET_PRIVATE should only be used if the property is known to exists on obj
# itself (it should really use %GetOwnProperty, but that would be way slower).
162
macro GLOBAL_PRIVATE(name) = (%CreateGlobalPrivateOwnSymbol(name));
163
macro NEW_PRIVATE_OWN(name) = (%CreatePrivateOwnSymbol(name));
164
macro IS_PRIVATE(sym) = (%SymbolIsPrivate(sym));
165
macro HAS_PRIVATE(obj, sym) = (%HasOwnProperty(obj, sym));
166
macro HAS_DEFINED_PRIVATE(obj, sym) = (!IS_UNDEFINED(obj[sym]));
167 168 169 170
macro GET_PRIVATE(obj, sym) = (obj[sym]);
macro SET_PRIVATE(obj, sym, val) = (obj[sym] = val);
macro DELETE_PRIVATE(obj, sym) = (delete obj[sym]);

171 172 173 174 175
# Constants.  The compiler constant folds them.
const NAN = $NaN;
const INFINITY = (1/0);
const UNDEFINED = (void 0);

176 177
# Macros implemented in Python.
python macro CHAR_CODE(str) = ord(str[1]);
178

179 180
# Constants used on an array to implement the properties of the RegExp object.
const REGEXP_NUMBER_OF_CAPTURES = 0;
181
const REGEXP_FIRST_CAPTURE = 3;
182 183 184 185 186

# We can't put macros in macros so we use constants here.
# REGEXP_NUMBER_OF_CAPTURES
macro NUMBER_OF_CAPTURES(array) = ((array)[0]);

187 188
# Limit according to ECMA 262 15.9.1.1
const MAX_TIME_MS = 8640000000000000;
189 190
# Limit which is MAX_TIME_MS + msPerMonth.
const MAX_TIME_BEFORE_UTC = 8640002592000000;
191

192 193
# Gets the value of a Date object. If arg is not a Date object
# a type error is thrown.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
macro CHECK_DATE(arg) = if (%_ClassOf(arg) !== 'Date') ThrowDateTypeError();
macro LOCAL_DATE_VALUE(arg) = (%_DateField(arg, 0) + %_DateField(arg, 21));
macro UTC_DATE_VALUE(arg)    = (%_DateField(arg, 0));

macro LOCAL_YEAR(arg)        = (%_DateField(arg, 1));
macro LOCAL_MONTH(arg)       = (%_DateField(arg, 2));
macro LOCAL_DAY(arg)         = (%_DateField(arg, 3));
macro LOCAL_WEEKDAY(arg)     = (%_DateField(arg, 4));
macro LOCAL_HOUR(arg)        = (%_DateField(arg, 5));
macro LOCAL_MIN(arg)         = (%_DateField(arg, 6));
macro LOCAL_SEC(arg)         = (%_DateField(arg, 7));
macro LOCAL_MS(arg)          = (%_DateField(arg, 8));
macro LOCAL_DAYS(arg)        = (%_DateField(arg, 9));
macro LOCAL_TIME_IN_DAY(arg) = (%_DateField(arg, 10));

macro UTC_YEAR(arg)        = (%_DateField(arg, 11));
macro UTC_MONTH(arg)       = (%_DateField(arg, 12));
macro UTC_DAY(arg)         = (%_DateField(arg, 13));
macro UTC_WEEKDAY(arg)     = (%_DateField(arg, 14));
macro UTC_HOUR(arg)        = (%_DateField(arg, 15));
macro UTC_MIN(arg)         = (%_DateField(arg, 16));
macro UTC_SEC(arg)         = (%_DateField(arg, 17));
macro UTC_MS(arg)          = (%_DateField(arg, 18));
macro UTC_DAYS(arg)        = (%_DateField(arg, 19));
macro UTC_TIME_IN_DAY(arg) = (%_DateField(arg, 20));

macro TIMEZONE_OFFSET(arg)   = (%_DateField(arg, 21));

macro SET_UTC_DATE_VALUE(arg, value) = (%DateSetValue(arg, value, 1));
macro SET_LOCAL_DATE_VALUE(arg, value) = (%DateSetValue(arg, value, 0));
224

225
# Last input and last subject of regexp matches.
226
const LAST_SUBJECT_INDEX = 1;
227 228
macro LAST_SUBJECT(array) = ((array)[1]);
macro LAST_INPUT(array) = ((array)[2]);
229 230

# REGEXP_FIRST_CAPTURE
231 232 233
macro CAPTURE(index) = (3 + (index));
const CAPTURE0 = 3;
const CAPTURE1 = 4;
234

235 236 237 238 239 240 241 242 243
# For the regexp capture override array.  This has the same
# format as the arguments to a function called from
# String.prototype.replace.
macro OVERRIDE_MATCH(override) = ((override)[0]);
macro OVERRIDE_POS(override) = ((override)[(override).length - 2]);
macro OVERRIDE_SUBJECT(override) = ((override)[(override).length - 1]);
# 1-based so index of 1 returns the first capture
macro OVERRIDE_CAPTURE(override, index) = ((override)[(index)]);

244
# PropertyDescriptor return value indices - must match
245
# PropertyDescriptorIndices in runtime-object.cc.
246 247 248 249 250 251 252
const IS_ACCESSOR_INDEX = 0;
const VALUE_INDEX = 1;
const GETTER_INDEX = 2;
const SETTER_INDEX = 3;
const WRITABLE_INDEX = 4;
const ENUMERABLE_INDEX = 5;
const CONFIGURABLE_INDEX = 6;
253 254 255 256 257 258 259 260 261 262 263 264 265 266

# For messages.js
# Matches Script::Type from objects.h
const TYPE_NATIVE = 0;
const TYPE_EXTENSION = 1;
const TYPE_NORMAL = 2;

# Matches Script::CompilationType from objects.h
const COMPILATION_TYPE_HOST = 0;
const COMPILATION_TYPE_EVAL = 1;
const COMPILATION_TYPE_JSON = 2;

# Matches Messages::kNoLineNumberInfo from v8.h
const kNoLineNumberInfo = 0;
267 268 269 270 271 272

# Matches PropertyAttributes from property-details.h
const PROPERTY_ATTRIBUTES_NONE = 0;
const PROPERTY_ATTRIBUTES_STRING = 8;
const PROPERTY_ATTRIBUTES_SYMBOLIC = 16;
const PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL = 32;
273 274 275 276 277

# Use for keys, values and entries iterators.
const ITERATOR_KIND_KEYS = 1;
const ITERATOR_KIND_VALUES = 2;
const ITERATOR_KIND_ENTRIES = 3;
278 279 280

# Check whether debug is active.
const DEBUG_IS_ACTIVE = (%_DebugIsActive() != 0);
281 282
macro DEBUG_IS_STEPPING(function) = (%_DebugIsActive() != 0 && %DebugCallbackSupportsStepping(function));
macro DEBUG_PREPARE_STEP_IN_IF_STEPPING(function) = if (DEBUG_IS_STEPPING(function)) %DebugPrepareStepInIfStepping(function);