Coverage Report

Created: 2026-03-07 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/sources/xsArguments.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016-2017  Moddable Tech, Inc.
3
 *
4
 *   This file is part of the Moddable SDK Runtime.
5
 *
6
 *   The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7
 *   it under the terms of the GNU Lesser General Public License as published by
8
 *   the Free Software Foundation, either version 3 of the License, or
9
 *   (at your option) any later version.
10
 *
11
 *   The Moddable SDK Runtime is distributed in the hope that it will be useful,
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *   GNU Lesser General Public License for more details.
15
 *
16
 *   You should have received a copy of the GNU Lesser General Public License
17
 *   along with the Moddable SDK Runtime.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * This file incorporates work covered by the following copyright and
20
 * permission notice:
21
 *
22
 *       Copyright (C) 2010-2016 Marvell International Ltd.
23
 *       Copyright (C) 2002-2010 Kinoma, Inc.
24
 *
25
 *       Licensed under the Apache License, Version 2.0 (the "License");
26
 *       you may not use this file except in compliance with the License.
27
 *       You may obtain a copy of the License at
28
 *
29
 *        http://www.apache.org/licenses/LICENSE-2.0
30
 *
31
 *       Unless required by applicable law or agreed to in writing, software
32
 *       distributed under the License is distributed on an "AS IS" BASIS,
33
 *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34
 *       See the License for the specific language governing permissions and
35
 *       limitations under the License.
36
 */
37
38
#include "xsAll.h"
39
40
static txBoolean fxArgumentsSloppyDefineOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* descriptor, txFlag mask);
41
static txBoolean fxArgumentsSloppyDeleteProperty(txMachine* the, txSlot* instance, txID id, txIndex index);
42
static txSlot* fxArgumentsSloppyGetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag);
43
static txSlot* fxArgumentsSloppySetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag);
44
45
const txBehavior ICACHE_FLASH_ATTR gxArgumentsSloppyBehavior = {
46
  fxArgumentsSloppyGetProperty,
47
  fxArgumentsSloppySetProperty,
48
  fxOrdinaryCall,
49
  fxOrdinaryConstruct,
50
  fxArgumentsSloppyDefineOwnProperty,
51
  fxArgumentsSloppyDeleteProperty,
52
  fxOrdinaryGetOwnProperty,
53
  fxOrdinaryGetPropertyValue,
54
  fxOrdinaryGetPrototype,
55
  fxOrdinaryHasProperty,
56
  fxOrdinaryIsExtensible,
57
  fxOrdinaryOwnKeys,
58
  fxOrdinaryPreventExtensions,
59
  fxOrdinarySetPropertyValue,
60
  fxOrdinarySetPrototype,
61
};
62
63
void fxBuildArguments(txMachine* the)
64
28.3k
{
65
28.3k
  mxPush(mxObjectPrototype);
66
28.3k
  mxArgumentsSloppyPrototype = *the->stack;
67
28.3k
  mxPop();
68
  
69
28.3k
  mxPush(mxObjectPrototype);
70
28.3k
  mxArgumentsStrictPrototype = *the->stack;
71
28.3k
  mxPop();
72
28.3k
}
73
74
txSlot* fxNewArgumentsSloppyInstance(txMachine* the, txIndex count)
75
234k
{
76
234k
  txSlot* environment = mxFrameToEnvironment(the->frame);
77
234k
  txSlot* instance;
78
234k
  txSlot* array;
79
234k
  txSlot* property;
80
234k
  txIndex index;
81
234k
  txSlot* address;
82
234k
  txIndex length = (txIndex)mxArgc;
83
234k
  instance = fxNewObjectInstance(the);
84
234k
  instance->flag |= XS_EXOTIC_FLAG;
85
234k
  array = instance->next = fxNewSlot(the);
86
234k
  array->flag = XS_INTERNAL_FLAG;
87
234k
  array->ID = XS_ARGUMENTS_SLOPPY_BEHAVIOR;
88
234k
  array->kind = XS_ARRAY_KIND;
89
234k
  array->value.array.length = 0;
90
234k
  array->value.array.address = C_NULL;
91
234k
  property = fxNextNumberProperty(the, array, length, mxID(_length), XS_DONT_ENUM_FLAG);
92
234k
  property = fxNextSlotProperty(the, property, mxFunction, mxID(_callee), XS_DONT_ENUM_FLAG);
93
234k
  property = fxNextSlotProperty(the, property, &mxArrayIteratorFunction, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG);
94
234k
  fxSetIndexSize(the, array, length, XS_CHUNK);
95
234k
  index = 0;
96
234k
  address = array->value.array.address;
97
234k
  property = the->scope + count;
98
280k
  while ((index < length) && (index < count)) {
99
45.4k
    *((txIndex*)address) = index;
100
45.4k
    address->ID = XS_NO_ID;
101
45.4k
    if ((property < environment) && (property->kind == XS_CLOSURE_KIND)) {
102
44.6k
      address->kind = property->kind;
103
44.6k
      address->value = property->value;
104
44.6k
    }
105
778
    else {
106
778
      txSlot* argument = mxArgv(index);
107
778
      address->kind = argument->kind;
108
778
      address->value = argument->value;
109
778
    }
110
45.4k
    index++;
111
45.4k
    address++;
112
45.4k
    property--;
113
45.4k
  }
114
237k
  while (index < length) {
115
2.40k
    property = mxArgv(index);
116
2.40k
    *((txIndex*)address) = index;
117
2.40k
    address->ID = XS_NO_ID;
118
2.40k
    address->kind = property->kind;
119
2.40k
    address->value = property->value;
120
2.40k
    index++;
121
2.40k
    address++;
122
2.40k
  }
123
234k
  return instance;
124
234k
}
125
126
txBoolean fxArgumentsSloppyDefineOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* descriptor, txFlag mask) 
127
130
{
128
130
  if (!id) {
129
108
    txSlot* property = fxGetIndexProperty(the, instance->next, index);
130
108
    if (property && (property->kind == XS_CLOSURE_KIND)) {
131
67
      txSlot* closure = property->value.closure;
132
67
      if (mask & XS_ACCESSOR_FLAG) {
133
7
        property->flag = closure->flag;
134
7
        property->kind = closure->kind;
135
7
        property->value = closure->value;
136
7
      }
137
60
      else if ((descriptor->flag & XS_DONT_SET_FLAG) && (mask & XS_DONT_SET_FLAG)) {
138
12
        property->flag = closure->flag;
139
12
        property->kind = closure->kind;
140
12
        property->value = closure->value;
141
12
        if (descriptor->kind != XS_UNINITIALIZED_KIND) {
142
3
          closure->kind = descriptor->kind;
143
3
          closure->value = descriptor->value;
144
3
        }
145
12
      }
146
67
    }
147
108
  }
148
130
  return fxOrdinaryDefineOwnProperty(the, instance, id, index, descriptor, mask);
149
130
}
150
151
txBoolean fxArgumentsSloppyDeleteProperty(txMachine* the, txSlot* instance, txID id, txIndex index)
152
7
{
153
7
  if (!id) {
154
7
    txSlot* property = fxGetIndexProperty(the, instance->next, index);
155
7
    if (property && (property->kind == XS_CLOSURE_KIND)) {
156
3
      if (property->value.closure->flag & XS_DONT_DELETE_FLAG)
157
0
        return 0;
158
3
    }
159
7
  }
160
7
  return fxOrdinaryDeleteProperty(the, instance, id, index);
161
7
}
162
163
txSlot* fxArgumentsSloppyGetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag)
164
208k
{
165
208k
  txSlot* result = fxOrdinaryGetProperty(the, instance, id, index, flag);
166
208k
  if (!id && result && result->kind == XS_CLOSURE_KIND)
167
198
    result = result->value.closure;
168
208k
  return result;
169
208k
}
170
171
txSlot* fxArgumentsSloppySetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag)
172
2.66k
{
173
2.66k
  txSlot* result = fxOrdinarySetProperty(the, instance, id, index, flag);
174
2.66k
  if (!id && result && result->kind == XS_CLOSURE_KIND)
175
0
    result = result->value.closure;
176
2.66k
  return result;
177
2.66k
}
178
179
txSlot* fxNewArgumentsStrictInstance(txMachine* the, txIndex count)
180
77.0k
{
181
77.0k
  txSlot* instance;
182
77.0k
  txSlot* array;
183
77.0k
  txSlot* property;
184
77.0k
  txSlot* function;
185
77.0k
  txIndex index;
186
77.0k
  txSlot* address;
187
77.0k
  txIndex length = (txIndex)mxArgc;
188
77.0k
  instance = fxNewObjectInstance(the);
189
77.0k
  instance->flag |= XS_EXOTIC_FLAG;
190
77.0k
  array = instance->next = fxNewSlot(the);
191
77.0k
  array->flag = XS_INTERNAL_FLAG;
192
77.0k
  array->ID = XS_ARGUMENTS_STRICT_BEHAVIOR;
193
77.0k
  array->kind = XS_ARRAY_KIND;
194
77.0k
  array->value.array.length = 0;
195
77.0k
  array->value.array.address = C_NULL;
196
77.0k
  property = fxNextNumberProperty(the, array, length, mxID(_length), XS_DONT_ENUM_FLAG);
197
77.0k
  property = fxNextSlotProperty(the, property, &mxArrayIteratorFunction, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG);
198
77.0k
  function = mxThrowTypeErrorFunction.value.reference;
199
77.0k
  property = property->next = fxNewSlot(the);
200
77.0k
  property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG;
201
77.0k
  property->ID = mxID(_callee);
202
77.0k
  property->kind = XS_ACCESSOR_KIND;
203
77.0k
  property->value.accessor.getter = function;
204
77.0k
  property->value.accessor.setter = function;
205
77.0k
  fxSetIndexSize(the, array, length, XS_CHUNK);
206
77.0k
  index = 0;
207
77.0k
  address = array->value.array.address;
208
77.1k
  while (index < length) {
209
42
    property = mxArgv(index);
210
42
    *((txIndex*)address) = index;
211
42
    address->ID = XS_NO_ID;
212
42
    address->kind = property->kind;
213
42
    address->value = property->value;
214
42
    index++;
215
42
    address++;
216
42
  }
217
77.0k
  return instance;
218
77.0k
}
219
220
void fxThrowTypeError(txMachine* the)
221
9
{
222
9
  if (mxFunction->value.reference->flag & XS_CAN_CONSTRUCT_FLAG)
223
1
    mxTypeError("secure mode");
224
8
  mxTypeError("strict mode");
225
9
}