-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove strict dependency on Node v6.10.x #1139
Changes from all commits
8de6c0e
02bd0a1
f443fb0
538f7d7
0cd309c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,19 +14,13 @@ TEST_FAST_TIMEOUT := 2m | |
include ../../build/common.mk | ||
|
||
export PATH:=$(shell yarn bin 2>/dev/null):$(PATH) | ||
export NODE_PATH:=$(NODE_PATH):./runtime/native/build/Release | ||
|
||
ensure:: | ||
cd runtime/native && ./ensure_node_v8.sh | ||
|
||
lint:: | ||
$(GOMETALINTER) cmd/pulumi-language-nodejs/main.go | sort ; exit "$${PIPESTATUS[0]}" | ||
tslint -c tslint.json -p tsconfig.json | ||
|
||
build:: | ||
go install -ldflags "-X github.com/pulumi/pulumi/pkg/version.Version=${VERSION}" ${LANGUAGE_HOST} | ||
cd runtime/native && node-gyp configure | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I expected to also see a boatload of red C++ code in this change? 😀 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. coming up in the next commit! 😆 |
||
cd runtime/native && node-gyp build | ||
tsc | ||
cp README.md ../../LICENSE package.json ./dist/* bin/ | ||
node ../../scripts/reversion.js bin/package.json ${VERSION} | ||
|
@@ -39,8 +33,6 @@ install:: | |
GOBIN=$(PULUMI_BIN) go install -ldflags "-X github.com/pulumi/pulumi/pkg/version.Version=${VERSION}" ${LANGUAGE_HOST} | ||
cp dist/pulumi-language-nodejs-exec "$(PULUMI_BIN)" | ||
cp dist/pulumi-resource-pulumi-nodejs "$(PULUMI_BIN)" | ||
mkdir -p "$(PULUMI_BIN)/$(shell node --version)" | ||
cp runtime/native/build/Release/nativeruntime-v0.11.0.node "$(PULUMI_BIN)/$(shell node --version)/nativeruntime-v0.11.0.node" | ||
rm -rf "$(PULUMI_NODE_MODULES)/$(NODE_MODULE_NAME)/tests" | ||
|
||
test_fast:: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
@set NODE_PATH=%NODE_PATH%;%~dp0\v6.10.2 | ||
@pulumi-language-nodejs-node.exe ./node_modules/@pulumi/pulumi/cmd/run %* | ||
@node ./node_modules/@pulumi/pulumi/cmd/run %* |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,2 @@ | ||
#!/bin/sh | ||
export NODE_PATH="$NODE_PATH:`dirname $0`/`node --version`" | ||
node ./node_modules/@pulumi/pulumi/cmd/dynamic-provider $@ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
@set NODE_PATH=%NODE_PATH%;%~dp0\v6.10.2 | ||
@pulumi-language-nodejs-node.exe ./node_modules/@pulumi/pulumi/cmd/dynamic-provider %* | ||
@node ./node_modules/@pulumi/pulumi/cmd/dynamic-provider %* |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
// Copyright 2016-2018, Pulumi Corporation. All rights reserved. | ||
|
||
// This file provides a low-level interface to a few V8 runtime objects. | ||
// We will use this low-level interface when serializing closures to walk the scope | ||
// chain and find the value of free variables captured by closures, as well as getting | ||
// source-level debug information so that we can present high-quality error messages. | ||
// | ||
// As a side-effect of importing this file, we must enable the --allow-natives-syntax V8 | ||
// flag. This is because we are using V8 intrinsics in order to implement this module. | ||
import * as v8 from "v8"; | ||
v8.setFlagsFromString("--allow-natives-syntax"); | ||
|
||
// We use four V8 intrinsics in this file. The first, `FunctionGetScript`, gets | ||
// a `Script` object given a JavaScript function. The `Script` object contains metadata | ||
// about the function's source definition. | ||
const getScript: (func: Function) => V8Script | undefined = | ||
// The use of the Function constructor here and elsewhere in this file is because | ||
// because V8 intrinsics are not valid JavaScript identifiers; they all begin with '%', | ||
// which means that the TypeScript compiler issues errors for them. | ||
new Function("func", "return %FunctionGetScript(func);") as any; | ||
|
||
// The V8 script object contains the name of the file that defined a function and a function | ||
// that convert a `V8SourcePosition` into a `V8SourceLocation`. (Conceptually - Positions are offsets | ||
// into a resource stream, while locations are objects with line and column information.) | ||
interface V8Script { | ||
readonly name: string; | ||
locationFromPosition(pos: V8SourcePosition): V8SourceLocation; | ||
} | ||
|
||
// The second intrinsic is `FunctionGetScriptSourcePosition`, which does about what you'd | ||
// expect. It returns a `V8SourcePosition`, which can be passed to `V8Script::locationFromPosition` | ||
// to produce a `V8SourceLocation`. | ||
const getSourcePosition: (func: Function) => V8SourcePosition = | ||
new Function("func", "return %FunctionGetScriptSourcePosition(func);") as any; | ||
|
||
// V8SourcePosition is an opaque value that should be passed verbatim to `V8Script.locationFromPosition` | ||
// in order to receive a V8SourceLocation. | ||
interface V8SourcePosition {} | ||
|
||
// V8SourceLocation contains metadata about a single location within a Script. For a function, it | ||
// refers to the last character of that function's declaration. | ||
interface V8SourceLocation { | ||
readonly line: number; | ||
readonly column: number; | ||
} | ||
|
||
// The last two intrinsics are `GetFunctionScopeCount` and `GetFunctionScopeDetails`. | ||
// The former function returns the number of scopes in a given function's scope chain, while | ||
// the latter function returns the i'th entry in a function's scope chain, given a function and | ||
// index i. | ||
const getFunctionScopeDetails: (func: Function, index: number) => any[] = | ||
new Function("func", "index", "return %GetFunctionScopeDetails(func, index);") as any; | ||
const getFunctionScopeCount: (func: Function) => number = | ||
new Function("func", "return %GetFunctionScopeCount(func);") as any; | ||
|
||
// `GetFunctionScopeDetails` returns a raw JavaScript array. This enum enumerates the objects that | ||
// are at specific indices of the array. We only care about one of these. | ||
enum V8ScopeDetailsFields { | ||
kScopeDetailsTypeIndex = 0, | ||
kScopeDetailsObjectIndex = 1, // <-- this one | ||
kScopeDetailsNameIndex = 2, | ||
kScopeDetailsStartPositionIndex = 3, | ||
kScopeDetailsEndPositionIndex = 4, | ||
kScopeDetailsFunctionIndex = 5, | ||
} | ||
|
||
// V8ScopeDetails contains a lot of information about a particular scope in the scope chain, but the | ||
// only one we care about is `scopeObject`, which is a mapping of strings to values. The strings are variables | ||
// declared within the given scope, and the values are the value of the captured variables. | ||
interface V8ScopeDetails { | ||
readonly scopeObject: Record<string, any>; | ||
} | ||
|
||
// getScopeForFunction extracts a V8ScopeDetails for the index'th element in the scope chain for the | ||
// given function. | ||
function getScopeForFunction(func: Function, index: number): V8ScopeDetails { | ||
const scopeDetails = getFunctionScopeDetails(func, index); | ||
return { | ||
scopeObject: scopeDetails[V8ScopeDetailsFields.kScopeDetailsObjectIndex] as Record<string, any>, | ||
}; | ||
} | ||
|
||
/** | ||
* Given a function and a free variable name, lookupCapturedVariableValue looks up the value of that free variable | ||
* in the scope chain of the provided function. If the free variable is not found, `throwOnFailure` indicates | ||
* whether or not this function should throw or return `undefined. | ||
* | ||
* @param func The function whose scope chain is to be analyzed | ||
* @param freeVariable The name of the free variable to inspect | ||
* @param throwOnFailure If true, throws if the free variable can't be found. | ||
* @returns The value of the free variable. If `throwOnFailure` is false, returns `undefined` if not found. | ||
*/ | ||
export function lookupCapturedVariableValue(func: Function, freeVariable: string, throwOnFailure: boolean): any { | ||
// The implementation of this function is now very straightforward since the intrinsics do all of the | ||
// difficult work. | ||
const count = getFunctionScopeCount(func); | ||
for (let i = 0; i < count; i++) { | ||
const scope = getScopeForFunction(func, i); | ||
if (freeVariable in scope.scopeObject) { | ||
return scope.scopeObject[freeVariable]; | ||
} | ||
} | ||
|
||
if (throwOnFailure) { | ||
throw new Error("Unexpected missing variable in closure environment: " + freeVariable); | ||
} | ||
|
||
return undefined; | ||
} | ||
|
||
/** | ||
* Given a function, returns the name of the file where this function was defined. | ||
* Returns the empty string if the given function has no Script. (e.g. a native function) | ||
*/ | ||
export function getFunctionFile(func: Function): string { | ||
const script = getScript(func); | ||
return script ? script.name : ""; | ||
} | ||
|
||
/** | ||
* Given a function, returns the line number in the file where this function was defined. | ||
* Returns 0 if the given function has no Script. | ||
*/ | ||
export function getFunctionLine(func: Function): number { | ||
const script = getScript(func); | ||
if (!script) { | ||
return 0; | ||
} | ||
|
||
const pos = getSourcePosition(func); | ||
const location = script.locationFromPosition(pos); | ||
return location.line; | ||
} | ||
|
||
/** | ||
* Given a function, returns the column in the file where this function was defined. | ||
* Returns 0 if the given function has no script. | ||
*/ | ||
export function getFunctionColumn(func: Function): number { | ||
const script = getScript(func); | ||
if (!script) { | ||
return 0; | ||
} | ||
|
||
const pos = getSourcePosition(func); | ||
const location = script.locationFromPosition(pos); | ||
return location.column; | ||
} |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yaay,